---
# System prepended metadata

title: VUE + VUEX

---

# 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/