應用四:Vue之VUEX狀態管理


 

(注:本文適用於有一定Vue基礎或開發經驗的讀者,文章就知識點的講解不一定全面,但卻是開發過程中很實用的)

 

概念:Vuex 是一個專為 Vue.js 應用程序開發的狀態管理模式。它采用集中式存儲管理應用的所有組件的狀態,並以相應的規則保證狀態以一種可預測的方式發生變化。

 

應用場景Vue多個組件之間需要共享數據或狀態。

 

Vuex有幾個核心概念:StateGetterMutationActionModule

 

State:存儲狀態數據

Getter:從狀態數據派生數據,相當於State的計算屬性。

Mutation:存儲用於同步更改狀態數據的方法,默認傳入的參數為state。

Action:存儲用於異步更改狀態數據,但不是直接更改,而是通過觸發Mutation方法實現,默認參數為context

ModuleVuex模塊化。

 

它們之間的交互關系如下圖(來源於官方文檔)所示:

接下來先看一個Vuex應用的簡單實例,新建store.js文件並添加如下代碼:

import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);

const store = new Vuex.Store({
  state: {
    name: ''
  },
  getters: {
    getName(state) {
      return 'hello ' + state.name;
    }
  },
  mutations: {
    mutationSetName(state, name) {
      state.name = name;
    }
  },
  actions: {
    actionSetName(context, name) {
      setTimeout(() => {
        context.commit('mutationSetName', name);
      }, 1000);
    }
  }
});
export default store;

 

然后將該store實例注入到所有子組件,方法如下:

import store from './store.js';
new Vue({
  el: '#app',
  router,
  // 把 store 對象提供給 “store” 選項,這可以把 store 的實例注入所有的子組件
  store,
  components: { App },
  template: '<App/>'
});

 

接下來就可以在vue的各個子組件中通過下面的方式訪問vuex對象實例。

this.$store.state.name;
this.$store.getters.getName;
this.$store.commit('mutationSetName', 'zhangsan');
this.$store.dispatch('actionSetName', 'lisi');

 

或者也可以通過輔助函數的方式訪問,

1、需要在應用的子組件中引入輔助函數

import {mapState, mapGetters, mapMutations, mapActions} from 'vuex'

2、在計算屬性computed中注入state和getters

computed: {
    ...mapState({
      // 把 `this.name` 映射為 `this.$store.state.name`
      name: state => state.name
    }),
    ...mapGetters({
      // 把 `this.getName` 映射為 `this.$store.getters.getName`
      getName: getName
    })
}

3、在methods中注入mutations和actions

methods: {
    ...mapMutations([
      // 將 `this.mutationSetName()` 映射為 `this.$store.commit('mutationSetName')`
      'mutationSetName'
    ]),
    ...mapActions([
      // 將 `this.actionSetName()` 映射為 `this.$store.dispatch('actionSetName')`
      'actionSetName'
    ])
}

 

模塊化

由於使用單一狀態樹,應用的所有狀態會集中到一個比較大的對象。當應用變得非常復雜時,store對象就有可能變得相當臃腫。

為了解決以上問題,Vuex允許我們將store分割成模塊。每個模塊擁有自己的stategettermutationaction、甚至是嵌套子模塊-從上到下進行同樣的分割。

 

下面新建moduleA和moduleB兩個js文件,分別添加如下代碼:

const moduleA = {
  namespaced: true,
  state: {
    name: ''
  },
  getters: {},
  mutations: {},
  actions: {}
}
export default moduleA;
const moduleB = {
  namespaced: true,
  state: {
    name: ''
  },
  getters: {},
  mutations: {},
  actions: {}
}
export default moduleB;

 

然后新建store.js文件並引入上述兩個模塊文件,代碼如下:

import moduleA from './moduleA.js';
import moduleB from './moduleB.js';
const store = new Vuex.Store({
  modules: {
    a: moduleA,
    b: moduleB
  }
})
export default store;

 

其中a、b為自定義的模塊別名,接下來按前文同樣的方式將store對象注入vue

訪問方式如下:

this.$store.state.a.name // -> moduleA 的狀態name
this.$store.state.b.name // -> moduleB 的狀態name

輔助函數訪問方式和前文所講區別不大,只是多了模塊名稱字段:

computed: {
    ...mapState('a', {
      name: state => state.name
    }),
    ...mapState('b', {
      name: state => state.name
    })
}

其他幾個對象gettermutationaction的訪問方式類似,都要加上模塊名稱字段。  

 

注意:

1、是否使用Vuex要根據項目的實際規模,在簡單的應用中使用 Vuex 可能會顯得繁瑣冗余;對於中大型的單頁應用,Vuex在狀態管理方面才是最好的選擇。

2、Vuex和單純的全局對象不同。Vuex 的狀態存儲是響應式的,當 Vue 組件從 store 中讀取狀態的時候,若 store 中的狀態發生變化,那么相應的組件也會相應地得到高效更新。

3、不能直接改變 store 中的狀態改變 store 中的狀態的唯一途徑就是顯式地提交 (commit) mutation,這樣有利於跟蹤每一個狀態的變化。

 

以上就是vuex的基礎用法,更多詳細的說明請查閱官方文檔:https://vuex.vuejs.org/zh/。 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM