###### tags: `VUE`
# Vue Vuex 取值的最佳實踐
## 簡介
這篇筆記探討在 Vue Vuex 中取得 store 值的最佳實踐,並針對不同的資料結構提供示例和解釋。
## 完整程式碼
```javascript=
// 頁面
<template>
<div class="d-flex flex-column justify-content-center w-100 h-100">
<div class="bg-primary p-1 mb-1 text-white">
<div
class="btn btn-light"
@click="$store.commit('order/SET_STORE1', Math.floor(Math.random() * 101))"
>
點我刷新
</div>
<div>$store.state.order.store1: {{ $store.state.order.store1 }}</div>
<div>computed 裡面 mapGetters store1: {{ store1 }}</div>
<div>dataD1: {{ dataD1 }}</div>
</div>
<div class="bg-primary p-1 mb-1 text-white">
<div
class="btn btn-light"
@click="$store.commit('order/SET_STORE2', {val: Math.floor(Math.random() * 101)})"
>
點我刷新
</div>
<div>$store.state.order.store2: {{ $store.state.order.store2 }}</div>
<div>computed 裡面 mapGetters store2: {{ store2 }}</div>
<div>dataD2: {{ dataD2 }}</div>
</div>
<div class="bg-primary p-1 mb-1 text-white">
<div
class="btn btn-light"
@click="$store.commit('order/SET_STE3', Math.floor(Math.random() * 101))"
>
點我刷新
</div>
<div>$store.state.order.store3: {{ $store.state.order.store3 }}</div>
<div>computed 裡面 mapGetters store3: {{ store3 }}</div>
<div>dataD3: {{ dataD3 }}</div>
</div>
<div class="bg-primary p-1 mb-1 text-white">
<div
class="btn btn-light"
@click="$store.commit('order/SET_STORE4', [Math.floor(Math.random() * 101)])"
>
點我刷新
</div>
<div>$store.state.order.store4: {{ $store.state.order.store4 }}</div>
<div>computed 裡面 mapGetters store4: {{ store4 }}</div>
<div>dataD3: {{ dataD4 }}</div>
</div>
<div class="bg-primary p-1 mb-1 text-white">
<div
class="btn btn-light"
@click="$store.commit('order/SET_STORE5', Math.floor(Math.random() * 101))"
>
點我刷新
</div>
<div>$store.state.order.store5: {{ $store.state.order.store5 }}</div>
<div>computed 裡面 mapGetters store5: {{ store5 }}</div>
<div>dataD3: {{ dataD4 }}</div>
</div>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
data() {
return {
dataD1: this.$store.state.order.store1,
dataD2: this.$store.state.order.store2,
dataD3: this.$store.state.order.store3,
dataD4: this.$store.state.order.store4,
dataD5: this.$store.state.order.store5,
}
},
computed: {
...mapGetters({
store1: 'order/store1',
store2: 'order/store2',
store3: 'order/store3',
store4: 'order/store4',
store5: 'order/store5',
}),
},
}
</script>
```
```javascript=
// store
export default {
namespaced: true,
state: {
store1: 1,
store2: {
val: 1,
},
store3: {
val: 1,
},
store4: [],
store5: [],
},
getters: {
store1: state => state.store1,
store2: state => state.store2,
store3: state => state.store3,
store4: state => state.store4,
store5: state => state.store5,
},
mutations: {
SET_STORE1(state, val) {
state.store1 = val
},
SET_STORE2(state, val) {
state.store2 = val
},
SET_STORE3(state, val) {
state.store3.val = val
},
SET_STORE4(state, val) {
state.store4 = val
},
SET_STORE5(state, val) {
state.store5.push(val)
},
},
}
```
## 注意事項
### 1. data 中的變數無法同步更新
在 template 中使用 `$store.state` 或 computed 的值會即時反應,但如果在 data 中聲明變數,則無法同步更新。以下是幾個例子:
#### dataD1 - 純文字

#### dataD2 - 物件
data 宣告的 dataD2 不會改變是因為 dataD2 只會取得原始物件,但是你是直接將新的物件直接覆蓋到 store 中而導致她不會觸發更新

#### dataD3 - 物件
data 宣告的 dataD3 會改變是因為你改變了原始物件裡面的參數,所以值會跟著改變
```
SET_STORE3(state, val) {
state.store3.val = val
},
```

#### dataD4 - 陣列

#### dataD5 - 陣列

## 結論
綜合以上,如果要取得 store 的值,建議使用 computed 屬性或是直接在 HTML 中使用 ```{{ store.val }}``` 來取得。避免在 data 中聲明變數,以確保畫面能夠正確地更新。