前言
在vue里丰滑,組件之間的作用域是獨(dú)立的悼粮,父組件跟子組件之間的通訊可以通過(guò)prop屬性來(lái)傳參,但是在兄弟組件之間通訊就比較麻煩了旬蟋。比如A組件要告訴一件事給B組件,那么A就要先告訴他們的爸組件革娄,然后爸組件再告訴B倾贰。當(dāng)組件比較多,要互相通訊的事情很多的話拦惋,爸組件要管他們那么多事匆浙,很累的。vuex正是為了解決這個(gè)問(wèn)題厕妖,讓多個(gè)子組件之間可以方便的通訊吞彤。
項(xiàng)目介紹
![image](https://raw.githubusercontent.com/lin-xin/notepad/master/screenshots/3.gif)
待辦事項(xiàng)中的一個(gè)事件,它可能擁有幾個(gè)狀態(tài)叹放,未完成、已完成挠羔、已取消或被刪除等井仰。這個(gè)事件需要在這多種狀態(tài)之間切換,那么使用vuex來(lái)管理也是非常方便的破加。
來(lái)看一下vuex怎么完成狀態(tài)管理的:
![image](https://raw.githubusercontent.com/lin-xin/notepad/master/screenshots/1.png)
所有組件都是調(diào)用actions俱恶,分發(fā)mutation去修改state,然后state經(jīng)過(guò)getter又更新到各個(gè)組件里范舀。state又通過(guò)localStorage存儲(chǔ)數(shù)據(jù)到本地合是,下次重新打開(kāi)時(shí)再讀取保存的數(shù)據(jù)。
模塊化
為什么要用模塊化锭环?當(dāng)我們的項(xiàng)目比較大聪全,組件很多,功能也多辅辩,會(huì)導(dǎo)致state里要存放很多內(nèi)容难礼,整個(gè) store 都會(huì)很龐大娃圆,很難管理。
我模塊化的store目錄如下:
|-store/ // 存放vuex代碼
| |-eventModule // 事件模塊
| | |-actions.js
| | |-getters.js
| | |-index.js
| | |-mutations.js
| | |-state.js
| |-themeModule // 主題顏色模塊
| | |-actions.js
| | |-getters.js
| | |-index.js
| | |-mutations.js
| | |-state.js
| |-index.js // vuex的核心蛾茉,創(chuàng)建一個(gè)store
可以看到讼呢,每個(gè)模塊擁有自己的state、mutation谦炬、action悦屏、getter,這樣子我們就可以把我們的項(xiàng)目根據(jù)功能劃分為多個(gè)模塊去使用vuex了键思,而且后期維護(hù)也不會(huì)一臉懵逼础爬。
狀態(tài)管理
接下來(lái),我們來(lái)看看vuex完成狀態(tài)管理的一個(gè)流程稚机。
舉個(gè)栗子:一個(gè)待辦事項(xiàng)幕帆,勾選之后,會(huì)在未完成列表里移除赖条,并在已完成的列表里出現(xiàn)失乾。這個(gè)過(guò)程,是這個(gè)待辦事項(xiàng)的狀態(tài)發(fā)生了改變纬乍。勾選的時(shí)候碱茁,是執(zhí)行了一個(gè)方法,那我們就先寫這個(gè)方法仿贬。在 event_list.vue 文件里新建一個(gè)moveToDone方法纽竣。
methods: {
moveToDone(id){ //移至已完成
this.$store.dispatch('eventdone', id);
}
}
在 moveToDone 方法中通過(guò) store.dispatch 方法觸發(fā) action, 接下來(lái)我們?cè)?eventModule/actions.js 中來(lái)注冊(cè)這個(gè) action, 接受一個(gè) id 的參數(shù)。
export default {
eventdone = ({ commit }, param) =>{
commit('EVENTDONE',{id: param});
}
}
action 通過(guò)調(diào)用 store.commit 提交載荷(也就是{id: param}這個(gè)對(duì)象)到名為'EVENTDONE'的 mutation茧泪,那我們?cè)賮?lái)注冊(cè)這個(gè) mutation
export default {
EVENTDONE(states,obj){
for (let i = 0; i < states.event.length; i++) {
if (states.event[i].id === obj.id) {
states.event[i].type = 2;
states.event[i].time = getDate();
var item = states.event[i];
states.event.splice(i, 1); // 把該事件在數(shù)組中刪除
break;
}
}
states.event.unshift(item); // 把該事件存到數(shù)組的第一個(gè)元素
local.set(states); // 將整個(gè)狀態(tài)存到本地
}
}
通過(guò) mutation 去修改 state, state里我們存放了一個(gè) event 屬性
export default {
event: []
};
在組件中要獲得這個(gè) state 里的 event, 那就需要寫個(gè)getters
export default {
getDone(states){
return states.event.filter(function (d) {
if (d.type === 2) { // type == 2表示已完成
return d; // 返回已完成的事件
}
});
}
};
然后每個(gè)module里都有一個(gè)index.js文件蜓氨,把自己的state、mutation队伟、action穴吹、getters都集合起來(lái),就是一個(gè)module
import * as func from '../function';
import actions from './actions.js';
import mutations from './mutations.js';
import state from './state.js';
import getters from './getters.js';
export default {
state,
getters,
actions,
mutations
}
在 store/index.js 里創(chuàng)建一個(gè) store 對(duì)象來(lái)存放這個(gè)module
import Vue from 'vue';
import Vuex from 'vuex';
import event from './eventModule';
Vue.use(Vuex);
export default new Vuex.Store({
modules: {
event
}
});
最后在 event_list.vue 組件上嗜侮,我們通過(guò)計(jì)算屬性 computed 來(lái)獲取到這個(gè)從未完成的狀態(tài)改變到已完成的狀態(tài)港令,我們要用到 store 這個(gè)對(duì)象里的getters
computed: {
getDone(){
return this.$store.getters.getDone;
}
}
這樣子,完成了 '未完成' => '已完成' 從提交修改到更新視圖讀取的整個(gè)流程锈颗,也是 vuex 工作的整個(gè)流程顷霹。通過(guò) module 的封裝,更加方便多模塊項(xiàng)目的開(kāi)發(fā)和維護(hù)击吱。