你不需要Vuex

黃景聖發表於2019-08-01

你不需要Vuex

對於Vuex這個的爭議,如果不是很高階的功能,我覺得自行定義一個class作為資料管理會更加好,理由就是在 vscode 編輯器上面的程式碼追蹤提示會非常有利於程式碼閱讀和維護,而且資料龐大的時候可以拆分為各class時,不管TS還是JS程式碼追蹤尤其重要,這個我也是從遊戲程式設計那邊借鑑來的習慣。

寫這篇文章的時候,我早就在2017年開始實際專案中使用class替代Vuex了,所以並不用擔心有其他問題,唯一要擔心的就是即將到來的Vue3.0,如果資料層的賦值不再是直接對等,而是像react中的this.setState這種方式去更新資料層的話,那這個使用方式就行不通了。

先來看下以下程式碼

const a = {
    value: 10
}
const b = a;

b.value = 20;

console.log(a, b); // 輸出 { value: 20 }, { value: 20 }
複製程式碼

先來說下原理:因為JavaScript變數對等賦值的時候,指標指向同一個記憶體,所以依賴這個特性和Vue中賦值是直接對等,就可以自行定義一些全域性的狀態屬性,依次注入到需要同步更新的元件中。廢話不多說,直接看程式碼結構:

step 1 store.js

// 自行定義一個class作為資料管理
class StoreModule{
    /** 訂單頁面列表資料 */
    order = {
        /** 訂單日期 */
        date: '2018/12/12 12:12:12',
        /** 訂單狀態 */
        state: 1
    }
}

/** 全域性資料 */
const Store = new StoreModule;

export default Store;
複製程式碼

step 2 goods.vue

<script>
// 可能是我的專案配置問題,這裡不用 @/ 而是使用相對路徑,不然vscode無法程式碼追蹤提示
import Store from '../module/store';
export default {
    data () {
        return {
            // 頁面例項化的時候獲取資料
            pageData: Store.order
        }
    }
}
</script>
複製程式碼

step 3 list.vue 同時用到store資料的元件

<script>
import Store from '../module/store';
export default {
    data () {
        return {
            // 頁面例項化的時候獲取資料
            listData: Store.order
        }
    },
    methods: {
        modifyState() {
            // 這裡修改了,其他引用到 Store.order 所有元件都會同步修改
            this.listData.state = 2;
        }
    }
}
</script>
複製程式碼

以上這個就是基本的狀態管理實現,說下我在專案中用到的狀態監聽處理:在StoreModule這個類裡面使用Object.defineProperty或者new Proxy,已經算是比較複雜的了。在VuexStateGetterMutationActionModule這些方法日常只會用到前3種,但對於新手來說,自定義的class作為狀態管理更容易理解,而且擴充套件性也高。

最後對比優缺點,優點:程式碼編輯器(以vs code為例)靜態程式碼追蹤提示非常友好(Vuex無法實現,所以我才放棄使用),資料龐大時尤其明顯,如果使用TS,配合 readonlyprivateenum 等使用,可維護、閱讀性簡直再舒服不過。缺點:瀏覽器中除錯外掛無法使用狀態追蹤,不過有了靜態程式碼分析檢測(僅限TS),也不需要除錯外掛了。

有問題歡迎提出~

最後附上使用到的參考專案:vue-admin

部落格地址:Hjs' blog

相關文章