Vuex中state小坑一記

       在樓主的一個自動化測試項目中,由於UI用例運行時間較長,要允許別人暫時去別的頁面做別的事情,然後返回時可以看到運行結果。要實現這個功能,就需要保存當前頁面數據,以便路由回來時還能獲取上次的數據。因此必須將原來單文件組件中的data數據移至vuex中的store裏面去保存。

       在做完更改後,發現部分數據丟失,並沒有恢復。通過vue-devtool查看state數據,發現出現了兩個targetKeys屬性,後來對比發現,原來其中一個叫targetKyes!這個屬性是哪裏來的?我的store模塊定義如下:

/**
 * 運行UI用例管理
 * */
import * as mutations from './mutations';
import * as actions from './actions';

const runUiCases = {
    state: { // state數據
        selectGroup:[],//下拉框選擇的用例組
        targetKeys:[],// 待跑用例id列表
        isRunning: false,//保存用例是否在運行狀態,用於長時間運行時,可以自由跳轉到別的頁面先做別的事,然後返回時判斷用例是否允許完畢
        groupList: [], //功能點列表
        casesList: [], // 用例列表
        reporter: {
            totalTime: 0,
            count: 0,
            passCount: 0,
            allPass: true,
            messageList: []
        } //結果
    },
    mutations,
    actions
};

export default runUiCases;

       很明顯,只有一個targetKeys屬性,並且按照一般的經驗,屬性一般都是要提前定義好的,不允許中途加屬性。後來想到能操縱state的只有mutation,翻到mutation一看,果然:

// 更新待跑用例keys
export const SET_TARGET_KEYS = (state, payload) => {// mutation第一個參數是state對象,第二個參數是傳進來的額外參數
    state.targetKyes = payload;
};

這裏由於拼寫錯誤,爲state添加了一個新的屬性!數據都保存到新屬性裏面去了,因此就出現了部分數據恢復不了的現象。

坑!怎麼能如此輕易的就可以改變state的數據?

特地去查了下官網,官網的描述如下:

Mutation 需遵守 Vue 的響應規則

       既然 Vuex 的 store 中的狀態是響應式的,那麼當我們變更狀態時,監視狀態的 Vue 組件也會自動更新。這也意味着 Vuex 中的 mutation 也需要與使用 Vue 一樣遵守一些注意事項:

  1. 最好提前在你的 store 中初始化好所有所需屬性。

  2. 當需要在對象上添加新屬性時,你應該

  • 使用 Vue.set(obj, 'newProp', 123), 或者

  • 以新對象替換老對象。例如,利用 stage-3 的對象展開運算符我們可以這樣寫:

    state.obj = { ...state.obj, newProp: 123 }

        說說我的看法。第1點很好理解,這樣做state有哪些屬性可以一目瞭然。可是!第2點,需要添加新屬性的時候使用Vue.set()還能說得過去,你直接新對象替換老對象也行?Excuse Me?這不是在埋坑嗎?到時候操作屬性的時候,A發現state沒有這個屬性,通過新對象替換老對象,添加了屬性。但其實這個屬性B已經用同樣的方式添加過了,而且類型不是A想要的那種。又或者,A想查看state有沒有某個屬性,他看了一眼state,沒有,卻不敢直接說沒有,因爲可能別的地方加了。

       因此,上述規則的第2點,我認爲不可取。後面出現新屬性,完全可以直接添加到state中去即可。如果你太懶,鐵了心要用第2種,我覺得使用Vue.set()也要比直接替換好很多!而且最好新屬性通過常量定義好,這樣查詢state有哪些屬性的時候,就可以從state和常量兩個地方查就夠了。但與其這麼麻煩,爲什麼不直接添加呢?

       回到我遇到的這個坑,如果mutation有限制,不能直接增刪屬性,必須通過類似mutation本身這樣機制,那這個問題就可以避免或者說提前暴露出來。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章