傻瓜式vuex語法糖kiss-vuex

halzhan發表於2018-12-21

前言

vuex 作為 vue 框架狀態資料管理模組,誕生已有些許年頭,它的出現很好地解決了兄弟元件響應式狀態資料通訊的問題。但是,vuex 的學習是一定門檻的,同時其宣告和使用方式有一些不夠簡潔。一般情況下,我們會使用 new Vue({store})這種方式注入 Store,在元件中使用很 mapGettersmapActions 等來引入 gettersactions 等,但隨著專案狀態資料增長,你會發覺越來越難以維護,因為這些資料和方法都太過分散。

看到這裡,如果你還是不懂 vuex 是何物,或者你已經使用了 vuex 但是很不習慣它的用法,沒有關係,你可以繼續閱讀本篇。實際上,在引入了 kiss-vuex 後,你甚至並不需要深刻理解 vuex 就能夠很好地使用它。

如果有糖和白水,你會作何選擇?我會選擇把糖放入白水,味道更為完美。

介紹

kiss-vuex 是一個非常簡單的語法糖類庫,遵循軟體工程裡的 KISS 原則,僅僅暴露一個方法:Store。壓縮版本僅僅只有 3KB,所以你可以放心加入到你的程式碼中。此處貼出幾個有用的連結:

安裝和使用

通過 npm

$ npm i kiss-vuex
複製程式碼

注意:需要先行安裝 vuevuex

在你的程式碼中,可以加入這樣一個 js 檔案:

// appStore.js
import { Store } from 'kiss-vuex';

@Store
class AppStore {
    counter = 0;
}

const appStore = new AppStore();

export { AppStore, appStore }
複製程式碼

OK,一個 store 就宣告好了。What!? 這麼簡單嗎?對,就是這麼簡單。

我們對比下原始的 store 的宣告方式:

import Vuex from 'vuex';

const appStore = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment (state) {
      state.count++
    }
  },
  actions: {
    increment (context) {
      context.commit('increment')
    }
  }
});

export { appStore }
複製程式碼

怎麼樣,是否有很明顯的差別?

kiss-vuex 提供了一種極為簡潔的宣告方式,通過 Store 裝飾器,你能夠快速獲得一個 Store 類,然後例項化匯出。在你需要使用到的地方將這個 store 引入,加入到元件的 computed 屬性下。

貼一段使用示例程式碼:

// hello.component.js
import Vue from 'vue';
import { appStore } from './AppStore';

export default Vue.component('app-hello', {
    template: 
        `<div>
            <p>Click times: {{counter}}</p>
            <button @click="doClick()">add counter</button>
        </div>`,
    computed: {
        counter() {
            return appStore.counter;
        }
    },
    methods: {
        doClick() {
            appStore.counter++;
        }
    }
})
複製程式碼

如果你有使用 Angular2+ 的經驗,不難看出 kiss-vuex 裡的 @StoreAngular 中的 @Service 十分類似。事實上,kiss-vuex 正是借鑑了這種模式,在未來的 vue3.0+ 版本中,也會有類似的語法特性。

當然,你依然可以使用函式呼叫的方式來宣告 store

// appStore.js
import { Store } from 'kiss-vuex';

// @Store
// class AppStore {
//     counter = 0;
// }

const appStore = Store({
    counter: 0
});

export { appStore }
複製程式碼

引入的話就和上述示例中一樣了。

另外,還有幾個線上例項可供參考:

額外配置

上述 @Store 這種使用方式是基於 es 中的裝飾器語法以及類屬性語法,而目前裝飾器和類屬性都處於草案狀態,所以需要讓你的開發環境支援這些語法特性,你需要做一些額外配置。

babel

如果你使用了 babel,需要安裝 @babel/plugin-proposal-decorators @babel/plugin-proposal-class-properties 兩個外掛:

$ npm i -D @babel/plugin-proposal-decorators @babel/plugin-proposal-class-properties
複製程式碼

並配置到 babel.config.js 中:

module.exports = {
    plugins: [
        ["@babel/plugin-proposal-decorators", { legacy: true }],
        ["@babel/plugin-proposal-class-properties", { loose: false }]
    ],
    presets: [
        [
            "@babel/env",
            {
                modules: false
            }
        ]
    ]
};
複製程式碼

typescript

如果你使用了 typescript,需要將 tsconfig.json 中的 compilerOptions.experimentalDecorators 這個屬性值設定為 true

{
    "compilerOptions": {
        "experimentalDecorators": true
    }
}
複製程式碼

es5

如果你偏愛 es5 環境,可以直接這麼使用:

<body>
    <script type="text/javascript" src="./node_modules/vue/dist/vue.min.js"></script>
    <script type="text/javascript" src="./node_modules/vuex/dist/vuex.min.js"></script>
    <script type="text/javascript" src="./node_modules/vuex/dist/kiss-vuex.min.js"></script>
    <script type="text/javascript">
        var appStore = KissVuex.Store({
            counter: 0
        });
        // 新增你的其餘自定義程式碼
    </script>
</body>
複製程式碼

後記

使用 kiss-vuex 能夠大大減少 store 相關程式碼量,並提倡“先引入後使用”這種模式,能夠很方便地進行維護和定位問題。有興趣的同學可以自行去 github 中檢視原始碼,思路也是非常巧妙的。

Enjoy and have fun :)

相關文章