Vuex是專爲Vue.js應用程序開發的狀態管理模式。它採用集中式存儲管理應用的全部組件的狀態,並以相應的規則保證狀態以一種可預測的方式發生變化。vue
對於深層嵌套組件,依靠props進行父子組件的傳遞顯得太過臃腫,並且難以維護。而vuex的出現就是爲了解決數據傳遞的問題。Vuex做爲一個全局管理倉庫,能夠管理全部組件的狀態state,不一樣組件之間也可依靠Vuex來共享狀態State。ios
1,Vuex的狀態存儲是響應式的。當Vue組件從store中讀取狀態時,若store的中的狀態發生變化,那麼相應的組件也會相應的獲得高效更新。web
2,改變store中狀態的惟一途徑就是顯式地提交mutation。全部的state的改變都必須通過mutation事件,方便咱們跟蹤每個狀態的的變化。vuex
負責存儲整個應用的狀態數據。在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;
當一個組件須要獲取多個狀態時,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'
])
},
複製代碼
上面說到,更改 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
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;
複製代碼