Vuex 模組化實現待辦事項的狀態管理

weixin_33807284發表於2017-03-14

前言

在vue裡,元件之間的作用域是獨立的,父元件跟子元件之間的通訊可以通過prop屬性來傳參,但是在兄弟元件之間通訊就比較麻煩了。比如A元件要告訴一件事給B元件,那麼A就要先告訴他們的爸元件,然後爸元件再告訴B。當元件比較多,要互相通訊的事情很多的話,爸元件要管他們那麼多事,很累的。vuex正是為了解決這個問題,讓多個子元件之間可以方便的通訊。

專案介紹

image

待辦事項中的一個事件,它可能擁有幾個狀態,未完成、已完成、已取消或被刪除等。這個事件需要在這多種狀態之間切換,那麼使用vuex來管理也是非常方便的。

來看一下vuex怎麼完成狀態管理的:

image

所有元件都是呼叫actions,分發mutation去修改state,然後state經過getter又更新到各個元件裡。state又通過localStorage儲存資料到本地,下次重新開啟時再讀取儲存的資料。

模組化

為什麼要用模組化?當我們的專案比較大,元件很多,功能也多,會導致state裡要存放很多內容,整個 store 都會很龐大,很難管理。

我模組化的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的核心,建立一個store

可以看到,每個模組擁有自己的state、mutation、action、getter,這樣子我們就可以把我們的專案根據功能劃分為多個模組去使用vuex了,而且後期維護也不會一臉懵逼。

狀態管理

接下來,我們來看看vuex完成狀態管理的一個流程。
舉個栗子:一個待辦事項,勾選之後,會在未完成列表裡移除,並在已完成的列表裡出現。這個過程,是這個待辦事項的狀態發生了改變。勾選的時候,是執行了一個方法,那我們就先寫這個方法。在 event_list.vue 檔案裡新建一個moveToDone方法。

methods: {
    moveToDone(id){ //移至已完成
        this.$store.dispatch('eventdone', id);
    }
}

在 moveToDone 方法中通過 store.dispatch 方法觸發 action, 接下來我們在 eventModule/actions.js 中來註冊這個 action, 接受一個 id 的引數。

export default {
    eventdone = ({ commit }, param) =>{
        commit('EVENTDONE',{id: param});
    }
}

action 通過呼叫 store.commit 提交載荷(也就是{id: param}這個物件)到名為'EVENTDONE'的 mutation,那我們再來註冊這個 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);          // 把該事件在陣列中刪除
                break;
            }
        }
        states.event.unshift(item);                 // 把該事件存到陣列的第一個元素
        local.set(states);                          // 將整個狀態存到本地
    }
}

通過 mutation 去修改 state, state裡我們存放了一個 event 屬性

export default {
    event: []
};

在元件中要獲得這個 state 裡的 event, 那就需要寫個getters

export default {
    getDone(states){
        return states.event.filter(function (d) {
            if (d.type === 2) {                 // type == 2表示已完成
                return d;                       // 返回已完成的事件
            }
        });
    }
};

然後每個module裡都有一個index.js檔案,把自己的state、mutation、action、getters都集合起來,就是一個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 裡建立一個 store 物件來存放這個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 元件上,我們通過計算屬性 computed 來獲取到這個從未完成的狀態改變到已完成的狀態,我們要用到 store 這個物件裡的getters

computed: {
    getDone(){
        return this.$store.getters.getDone;
    }
}

這樣子,完成了 '未完成' => '已完成' 從提交修改到更新檢視讀取的整個流程,也是 vuex 工作的整個流程。通過 module 的封裝,更加方便多模組專案的開發和維護。

演示地址 : demo

原始碼地址 : notepad

更多文章 : blog

相關文章