?
このドキュメントでは、 php中國語ネットマニュアル リリース
Vuex 使用 單一狀態(tài)樹 - 是的,用一個對象就包含了全部的應用層級狀態(tài),然后作為一個『唯一數(shù)據(jù)源(SSOT)』而存在。這也意味著,每一個應用將只有一個 store 實例。單一狀態(tài)樹讓我們能夠直接地定位任一特定的狀態(tài)片段,在調(diào)試的過程中也能輕易地取得整個當前應用狀態(tài)的快照。
單狀態(tài)樹和模塊化并不沖突 - 在后面的章節(jié)里我們會討論如何將狀態(tài)(state)和狀態(tài)變更事件(mutation)分布到各個子模塊中。
那么我們?nèi)绾卧?Vue 組件中展示狀態(tài)呢?由于 Vuex 的狀態(tài)存儲是響應式的,從 store 實例中讀取狀態(tài)最簡單的方法,就是在計算屬性的函數(shù)中直接返回某個 store 的狀態(tài):
// 創(chuàng)建一個計數(shù)器組件 const Counter = { template: `<div>{{ count }}</div>`, computed: { count () { return store.state.count } } }
當 store.state.count
發(fā)生變化,將會引發(fā)重新對計算屬性取值,并且相關(guān)聯(lián)的 DOM 將觸發(fā)更新。
然而,這種模式導致組件依賴于全局狀態(tài)單例。當使用模塊系統(tǒng)時,還需要在每個組件都去引入 store,才能使每個組件都能使用 store 的狀態(tài),同時測試組件時也需要模擬出 store。
Vuex 提供一個機制,設置 store
選項(啟用Vue.use(Vuex)
)將 store 從根組件『注入』到每一個子組件中:
const app = new Vue({ el: '#app', // 使用 "store" 選項后,可以注冊 store 對象。將會把 store 實例注入到所有子組件。 store, components: { Counter }, template: ` <div class="app"> <counter></counter> </div> ` })
通過在根實例中注冊 store
選項,該 store 實例會被注入到根組件下的所有子組件中,并且子組件可以通過 this.$store
來訪問。讓我們一起調(diào)整剛才 計數(shù)器
的實現(xiàn):
const Counter = { template: `<div>{{ count }}</div>`, computed: { count () { return this.$store.state.count } } }
mapState
工具
當一個組件需要引用 store 的多個 state 屬性或 getter 函數(shù)時,聲明列舉出所有計算屬性會變得重復且繁瑣。為了解決這個問題,我們可以使用 mapState
工具,它為我們生成 computed 所需的很多個 getter 函數(shù),幫助我們節(jié)省一些鍵盤按鍵(^_^):
// vuex 提供了獨立的構(gòu)建工具函數(shù) Vuex.mapState import { mapState } from 'vuex' export default { // ... computed: mapState({ // 箭頭函數(shù)可以讓代碼非常簡潔 count: state => state.count, // 傳入字符串 'count' 等同于 `state => state.count` countAlias: 'count', // 想訪問局部狀態(tài),就必須借助于一個普通函數(shù),函數(shù)中使用 `this` 獲取局部狀態(tài) countPlusLocalState (state) { return state.count + this.localCount } }) }
當計算屬性名稱和狀態(tài)子樹名稱對應相同時,我們可以向 mapState
工具函數(shù)傳入一個字符串數(shù)組。
computed: mapState([ // 映射 state.count 到 store.this.count 'count' ])
注意,mapState
返回一個對象。我們?nèi)绾问褂?mapState 合并其他局部的計算屬性呢?通常地,為了將多個對象合并為一個對象,再把這個合并好的最終對象傳入到 computed
屬性去,我們不得不使用一個工具函數(shù)來實現(xiàn)。然而有了對象擴展運算符(ECMAScript 提案 stage-3),我們可以大大簡化語法:
computed: { localComputed () { /* ... */ }, // 使用對象擴展運算符,將 mapState 返回的對象和外層其他計算屬性混合起來 ...mapState({ // ... }) }
使用 Vuex 并不意味你應該把 所有 狀態(tài)都放在 Vuex 中去管理。盡管把更多的狀態(tài)放到 Vuex 管理,會讓狀態(tài)變化變得更加清晰和可調(diào)試,但有時也能使代碼變得冗余和不直觀。如果某部分狀態(tài)嚴格屬于一個單獨的組件,那就只把這部分狀態(tài)作為局部狀態(tài)就好了。你應該權(quán)衡利弊,做適合您的 App 開發(fā)需求的決策。