###### 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 - 純文字 ![D1](https://hackmd.io/_uploads/rytk4Z2Pa.gif) #### dataD2 - 物件 data 宣告的 dataD2 不會改變是因為 dataD2 只會取得原始物件,但是你是直接將新的物件直接覆蓋到 store 中而導致她不會觸發更新 ![D2](https://hackmd.io/_uploads/B1tDBb3Pa.gif) #### dataD3 - 物件 data 宣告的 dataD3 會改變是因為你改變了原始物件裡面的參數,所以值會跟著改變 ``` SET_STORE3(state, val) { state.store3.val = val }, ``` ![D3](https://hackmd.io/_uploads/Sk3za-2vT.gif) #### dataD4 - 陣列 ![D4](https://hackmd.io/_uploads/Sko5Ob2wp.gif) #### dataD5 - 陣列 ![D5](https://hackmd.io/_uploads/BkdcOZ2Pp.gif) ## 結論 綜合以上,如果要取得 store 的值,建議使用 computed 屬性或是直接在 HTML 中使用 ```{{ store.val }}``` 來取得。避免在 data 中聲明變數,以確保畫面能夠正確地更新。