vuex狀態管理使用
1.前言:
Vuex 是一個專為 Vue.js 應用程式開發的狀態管理模式,可以理解為一個共享倉庫,可以實現多個元件共享狀態。
每一個 Vuex 應用的核心就是 store(倉庫),兩個特點:
1)Vuex 的狀態儲存是響應式的。當 Vue 元件從 store 中讀取狀態的時候,若 store 中的狀態發生變化,那麼相應的元件也會相應地得到高效更新;
2)改變 store 中的狀態的唯一途徑就是顯式地提交 (commit) mutation,這樣做的好處是方便地跟蹤每一個狀態的變化
2. state
const state = { count: 123 } export default new Vuex.Store({ strict: true, state, mutations, getters, actions })
state為單一狀態樹,在state中需要定義我們所需要管理的陣列、物件、字串等等,只有在這裡定義了,在vue.js的元件中才能獲取你定義的這個物件的狀態;
由於 Vuex 的狀態儲存是響應式的,從 store 例項中讀取狀態最簡單的方法就是在計算屬性中返回某個狀態
computed: { count () { // 傳統方式(mapState) return this.$store.state.count } },
// 在單獨構建的版本中輔助函式為 mapState import { mapState } from 'vuex'
export default { // ... computed: mapState({ // 箭頭函式可使程式碼更簡練 count: state => state.count,
// 傳字串引數 'count' 等同於 `state => state.count` countAlias: 'count' }) }
computed: mapState([ // 對映名一樣時, 對映 this.count 為 store.state.count 'count' ]) computed: { localComputed () { ... }, // 使用物件展開運算子將此物件混入到外部物件中 ...mapState({ // ... }) }
3. getter
getter有點類似vue.js的計算屬性,當我們需要從store的state中派生出一些狀態,那麼我們就需要使用getter,getter會接收state作為第一個引數,而且getter的返回值會根據它的依賴被快取起來,只有getter中的依賴值(state中的某個需要派生狀態的值)發生改變的時候才會被重新計算。
getters: {
todoOri: (state) => state.todos
todo: (state) => state.todos.filter(todo => todo.done)
}
使用賦值函式mapGetters
computed: { // 使用物件展開運算子將 getter 混入 computed 物件中 ...mapGetters([ 'doneTodosCount', 'anotherGetter', // ... ]) }
mapGetters({ // 把 `this.doneCount` 對映為 `this.$store.getters.doneTodosCount` doneCount: 'doneTodosCount' })
4.mutation(方便地跟蹤每一個狀態的變化)
更改store中state狀態的唯一方法就是提交mutation,就很類似事件。每個mutation都有一個字串型別的事件型別和一個回撥函式,我們需要改變state的值就要在回撥函式中改變。我們要執行這個回撥函式,那麼我們需要執行一個相應的呼叫方法:store.commit。 使用常量替代 mutation 事件型別,把這些常量放在單獨的檔案中(mutation-types.js)可以讓你的程式碼合作者對整個 app 包含的 mutation 一目瞭然; mutation 必須是同步函式; 例如,當你呼叫了兩個包含非同步回撥的 mutation 來改變狀態,你怎麼知道什麼時候回撥和哪個先回調呢
mapMutations 輔助函式 import { mapMutations } from 'vuex'
export default { // ... methods: { ...mapMutations([ 'increment', // 將 `this.increment()` 對映為 `this.$store.commit('increment')`
// `mapMutations` 也支援載荷: 'incrementBy' // 將 `this.incrementBy(amount)` 對映為 `this.$store.commit('incrementBy', amount)` ]), ...mapMutations({ add: 'increment' // 將 `this.add()` 對映為 `this.$store.commit('increment')` }) } }
5. action
action 提交的是 mutation,而不是直接變更狀態; action 可以包含任意非同步操作 action 函式接受一個與 store 例項具有相同方法和屬性的 context 物件,因此你可以呼叫 context.commit 提交一個 mutation,或者通過 context.state 和 context.getters 來獲取 state 和 getters action 通過 store.dispatch 方法觸發; 你在元件中使用 this.$store.dispatch('xxx') 分發 action,或者使用 mapActions 輔助函式將元件的 methods 對映為 store.dispatch 呼叫(需要先在根節點注入 store)
import { mapActions } from 'vuex'
export default { // ... methods: { ...mapActions([ 'increment', // 將 `this.increment()` 對映為 `this.$store.dispatch('increment')`
// `mapActions` 也支援載荷: 'incrementBy' // 將 `this.incrementBy(amount)` 對映為 `this.$store.dispatch('incrementBy', amount)` ]), ...mapActions({ add: 'increment' // 將 `this.add()` 對映為 `this.$store.dispatch('increment')` }) } }