# VUE + VUEX ## VUE ### data 放狀態 ### components 放元件 ### methods - 每次呼叫都會重新執行算出新的結果 ### computed ```js <script> export default { data() { return { firstName: 'Foo', lastName: 'Bar', } }, computed: { fullName() { return this.firstName + ' ' + this.lastName }, }, } </script> ``` - firstName, LastName 變化時會執行算出新的結果 - 沒變化時會取 cache # VUEX 什麼時候用 VUEX ``` gco not_use_vuex ``` 1. component 有很多層,參數要通過很多層 component 傳遞 ```js SiemAppForm.vue closeModal -> NewModal.vue closeModal -> App.vue closeNewModal ``` 2. 不想在每個元件有重複的 component, method, data, 套件 ```js loader NewModal.vue ``` # ## 引入 VUEX ```js #main.js ... import store from './store/store'; new Vue({ store, render: (h) => h(App), }).$mount('#siem-app'); ``` ```js #store.js import Vuex from 'vuex'; Vue.use(Vuex); export default new Vuex.Store({ ... }) ``` ## store VUEX 的設定都會在 store.js ### state - 用來放component 會用到的狀態 - 類似 data - state 在component 會放在 computed,才會在改變後拿到新的值 ```js ... computed: { modal() { return this.$store.state.modal; }, loading() { return this.$store.state.loading; }, siemApps() { return this.$store.state.siemApps; }, }, ``` - mapState ```js import { mapState } from "vuex"; ... export default { ... computed: mapState({ modal: "myModal", loading: "isLoading" }), ... } ``` ```js computed: mapState(['modal', 'loading', 'siemApps']), ``` ```js computed: { ...mapState(['modal', 'loading', 'siemApps']), isNewForm() { return this.$store.state.modal.new; }, }, ``` ### mutations state 變數不能直接改變(跟data不同) 直接改變 state 的方法再放這邊 參數: state, ststus ```js store.js export default new Vuex.Store({ state: { loading: false, ... } ... mutations: loading(state, status) { state.loading = status; }, ... )} ``` 使用: ```js this.$store.commit('loading', true); this.$store.commit('loading', false); ``` mathod 跟 mutation 同名也可以用mapMutations ```js methods: mapMutations(["Loaded", "addTimes"]) ``` ### actions 非同步的方法放這邊,不會直接改變 state (ex.會打到後端的方法) 參數: context(commit, dispatch), payload ![](https://i.imgur.com/6Z24Efu.png) #直接用method ```js #component async toggleActive() { try { this.$store.commit('loading', true); const response = await api.patch(`/siem_apps/${this.siemApp.id}`, { active: !this.siemApp.active, }); if (response.success === false) { if (response.message) { alertify.error(response.message); } } else { const { siem_app } = response; this.$store.commit('updateSiemApp', siem_app); alertify.success('Updated success.'); } } catch (e) { alertify.error(e.message); } this.$store.commit('loading', false); }, ``` #用actions ```js #store.js ... actions: { async updateSiemApp({ commit }, payload) { const response = await api.patch(`${ajaxBaseUrl}/${payload.id}`, payload); try { const { siem_app } = response; commit('updateSiemApp', siem_app); } catch (err) { throw new Error('Fail...'); } } }, ... ``` ```js #component ... toggleActive() { this.$store.dispatch('updateSiemApp', { id: this.siemApp.id, active: !this.siemApp.active }) .then(() => { alertify.success('Updated success.'); }) .catch((err) => { alertify.error(err.message); }) .then(() => { this.$store.commit('loading', false); }); }, ``` 好處: - 不用每個component 都 import axios - component method 只要準備好參數跟 message,改資料都給 store 做 壞處: - code 分散在兩邊 - 沒有重複使用的話 code 變很多 ``` gco feature/siem_apps ``` REF: https://peterhpchen.github.io/VuejsQuest/basic/04_Lifecycle.html#%E5%90%84%E9%9A%8E%E6%AE%B5%E7%9A%84%E9%89%A4%E5%AD%90%E5%87%BD%E5%BC%8F https://medium.com/itsems-frontend/vue-vuex2-actions-7764ebed3962 https://cythilya.github.io/2017/04/15/vue-computed/