Vuex的使用

Vuex是專爲Vue.js應用程序開發的狀態管理模式。它採用集中式存儲管理應用的全部組件的狀態,並以相應的規則保證狀態以一種可預測的方式發生變化。vue

應用場景

對於深層嵌套組件,依靠props進行父子組件的傳遞顯得太過臃腫,並且難以維護。而vuex的出現就是爲了解決數據傳遞的問題。Vuex做爲一個全局管理倉庫,能夠管理全部組件的狀態state,不一樣組件之間也可依靠Vuex來共享狀態State。ios

Vuex不一樣於單純的全局對象

1,Vuex的狀態存儲是響應式的。當Vue組件從store中讀取狀態時,若store的中的狀態發生變化,那麼相應的組件也會相應的獲得高效更新。web

2,改變store中狀態的惟一途徑就是顯式地提交mutation。全部的state的改變都必須通過mutation事件,方便咱們跟蹤每個狀態的的變化。vuex

核心概念

state

負責存儲整個應用的狀態數據。在vue組件中獲取Vuex狀態的方式以下,在計算屬性中返回某個狀態:vue-cli

1,須要在DOM節點上獲取到狀態;axios

實現:在項目中,在組件中把存在Vuex中的「columns」取出來,並顯示在該組件上api

1),在computed中返回該狀態。bash

computed: {
    columns(){
        return this.$store.state.columns;
    }
},
複製代碼

2),在須要用到的dom節點上進行操做。框架

<el-col :span="20">
    <el-checkbox-group   v-model="column">
        <el-checkbox :label="item.name" v-for="(item,index) in columns" :key="index">{{item.name}}</el-checkbox>
    </el-checkbox-group>
</el-col>
複製代碼

結果:每當store.state.columns變化時,都會從新計算屬性,而且觸發更新相關聯的DOM。 2,在vue生命週期中獲取到Vuex中的狀態,能夠直接用this.$store.state對象dom

eg:

this.id = this.$store.state.articleId;

mapState輔助函數

當一個組件須要獲取多個狀態時,vuex提供了mapState輔助函數生成計算屬性。

實現:從Vuex中獲取「activityLeft」和「columns」兩個狀態時,能夠按如下兩個方式獲取。

1),直接獲取

computed: {
  activityLeft(){
    return this.$store.state.activityLeft;
  },
  columns(){
    return this.$store.state.columns;
  }
}
複製代碼

2),用mapState輔助函數輔助函數獲取

computed: {
    ...mapState([
       'activityLeft',
       'columns'
    ])
 },
複製代碼

mutation

上面說到,更改 Vuex 的 store 中的狀態的惟一方法是提交 mutation。

Vuex 中的mutation很是相似於事件:每一個 mutation 都有一個字符串的 事件類型 (type) 和 一個 回調函數 (handler)。

實現:在組件中改變Vuex狀態中的acticleId狀態,不能夠用「this.$store.state.articleId = 1」這種方式進行修改,須要如下面的方面進行修改。

eg:

1),組件中須要用state.commit來喚醒mutation中的handler。例如在點擊編輯時,獲取到該item的id傳遞給對應的handler

handleCurrentChange(id) {
   this.$store.commit("getArticleId",id);
 }
複製代碼

2),在Vuex中添加一一對應的handler

mutations:{
   getArticleId(state,id){
     state.articleId = id;
   },  
}
複製代碼

注意:

1,最好在提早在你的 store 中初始化好全部所需屬性。上述例子應該在state中先初始化好articleId。

2,mutation必須是同步函數。在 mutation 中混合異步調用會致使你的程序很難調試,若是須要處理異步操做,可使用Action

Action

1,Action 提交的是 mutation,而不能直接變動狀態

2,Action 能夠包含任意異步操做

實現:在項目中,在Action中使用axios去獲取數據,並把數據存進Vuex的狀態裏面。

1),在組件的methods中經過 store.dispatch 方法觸發Action

handleSizeChange(val) {
  this.pageSize = val;
    let data = {
      "type":this.$store.state.navName,
      "wid":this.$store.state.websiteId,
      "pageSize":this.pageSize,
      "pageNum":this.pageNum,
      "searchTitle":this.searchTitle
     };
   this.$store.dispatch("getArticle",data);
},
複製代碼

2),在Vuex註冊一一對應的Action

actions:{
  getArticle({commit},{type='',searchTitle='',wid,pageNum=1,pageSize=20}){
    axios.post(api.url+'articleList',{
      type:type,
      searchTitle:searchTitle,
      wid:wid,
      pageSize:pageSize,
      pageNum:pageNum
    }).then((response)=>{
      if(response.data.ret == 0){
        var data = response.data;
        var msg = data.msg;
        var total = data.total;
        commit('getArticle',{msg,total})
      }
    });
  },
}
複製代碼

3),經過提交 mutation 來記錄狀態變動

mutations:{
  getArticle(state,data){
    var res = data.msg;
    state.activityList = res;
    state.total = data.total;
  },
}
複製代碼

重點:store.dispatch 能夠處理被觸發的 action 的處理函數返回的 Promise,而且 store.dispatch 仍舊返回 Promise:

eg:一個 store.dispatch 在不一樣模塊中能夠觸發多個 action 函數。

actions: {
  async actionA ({ commit }) {
    commit('gotData', await getData())
  },
  async actionB ({ dispatch, commit }) {
    await dispatch('actionA') // 等待 actionA 完成
    commit('gotOtherData', await getOtherData())
  }
}
複製代碼

以上就是我在項目中基於vue-cli框架中使用Vuex的一些例子。最後上面提到的vuex狀態附在下列store.js中。

import Vue from 'vue';
import Vuex from 'vuex';
import axios from 'axios';
import api from '../api/api.js';
Vue.use(Vuex);
let store = new Vuex.Store({
  state:{
    columns:[],
    articleId:'',
  },
  mutations:{
    getArticle(state,data){
      var res = data.msg;
      state.activityList = res;
      state.total = data.total;
    },
    getArticleId(state,id){
      state.articleId = id;
    },
  },
  actions:{
    getArticle({commit},{type='',searchTitle='',wid,pageNum=1,pageSize=20}){
      axios.post(api.url+'articleList',{
        type:type,
        searchTitle:searchTitle,
        wid:wid,
        pageSize:pageSize,
        pageNum:pageNum
      }).then((response)=>{
        if(response.data.ret == 0){
          var data = response.data;
          var msg = data.msg;
          var total = data.total;
          commit('getArticle',{msg,total})
        }
      });
    },
  }    
});
export default store;
複製代碼
相關文章
相關標籤/搜索