# 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

#直接用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/