vue高階進階系列——用typescript玩轉vue和vuex

徐小夕發表於2019-04-27

       用過vue的朋友大概對vuex也不陌生,vuex的官方解釋是專為 Vue.js 應用程式開發的狀態管理模式。它採用集中式儲存管理應用的所有元件的狀態,並以相應的規則保證狀態以一種可預測的方式發生變化。說的簡單點就是對vue的狀態進行統一管理,如下圖介紹了其管理模式:

image.png

最簡單的使用方法長這樣的:

// 如果在模組化構建系統中,請確保在開頭呼叫了 Vue.use(Vuex)

const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment (state) {
      state.count++
    }
  }
})
複製程式碼

如果專案中需要管理的狀態很多,也可以將這些方法按檔案分開,最後掛載在index檔案下:

// state.js
export default {
    total: 0
}
複製程式碼
// mutaction.js
export default {
    add(state){
      state++
  }
}
複製程式碼
// action.js
export default {
    addAsync(context){
     setTimeout(() => {
            context.commit('add');
     }, 1000);
  }
}
複製程式碼

最後統一匯入到index.js

// index.js
import Vue from 'vue';
import Vuex from 'vuex';
import { state } from './state';
import mutations from './mutation';
import actions from './action';

Vue.use(Vuex);

export default new Vuex.Store({
  state,
  mutations,
  actions,
});
複製程式碼

完畢,這就是基本的vuex的開發模式。接下來,我不會過多介紹vuex的用法,而是介紹如何基於typescript,用class的方式來使用vue和vuex進行專案開發,相信使用過react的朋友們對class的寫法不會陌生,那就讓我們開始吧!

       為了省去一些配置上的麻煩,我們直接採用vue-cli3來搭建專案。在建立專案的時候選中typescript即可。

image.png

建立完專案之後,我們對專案結構進行調整,使其更易於維護和管理,如下:

image.png
接下來開始我們的程式碼編寫,首先關注store目錄,這是我們管理專案狀態的地方,我們將state改寫成typescript的方式:

export interface State {
    name: string;
    total: number;
    isLogin: boolean;
    postList: object[];
}

export const state: State = {
    name: '',
    total: 0,
    isLogin: false,
    postList: [],
};
複製程式碼

如果對typescript不熟悉的同學,可以移步到typescript官網去了解基本用法。

action檔案和之前沒有太大變化,只是增加了型別定義和引數:

export default {
    asyncAdd(context: any, paylod: any) {
        setTimeout(() => {
            context.commit('add', paylod.num);
        }, 1000);
    },
};
複製程式碼

下面是mutaction檔案:

import { State } from './state';

export default {
    add(state: State, payload: any) {
        payload ? (state.total += payload) : state.total++;
    },
};
複製程式碼

說到這裡,有必要簡單講解一下action和mutaction的區別: Action 類似於 mutation,不同在於:

  • Action 提交的是 mutation,而不是直接變更狀態。
  • Action 可以包含任意非同步操作。 說簡單點就是mutation用於同步執行,action用於非同步執行,可以多重分發mutation。

       完成了這些,vuex的工作大致告於段落,接下來我們關注的重點就是頁面元件和如何在元件中使用vuex。

// home.vue
<template>
  <div class="home">
    <img alt="Vue logo" src="../assets/logo.png">
    <HelloWorld :msg="name" />
    <div @click="onclick">{{name}}</div>
    <div @click="add">同步增加總數:{{total}}</div>
    <div @click="addAsync(1)">非同步增加總數:{{total}}</div>
  </div>
</template>

<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import { mapMutations } from 'vuex';
import HelloWorld from '@/components/HelloWorld.vue'; // @ is an alias to /src

@Component({
  components: {
    HelloWorld,
  },
})
export default class Home extends Vue {
  public name: string = 'xujiang';

  public onclick(): void {
    this.name = 'hello world';
  }

  public add() {
    this.$store.commit('add');
  }

  public addAsync(num: any) {
    this.$store.dispatch('asyncAdd', {num});
  }

  get total(): void {
    return this.$store.state.total;
  }
}
</script>
複製程式碼

相信用過react的朋友對這種寫法並不陌生,其實vue完全可以將模版寫法改寫成jsx的方式,就好比寫react的jsx檔案一樣,後面我會推出一篇文章,專門介紹如何使用jsx+class的方式開發vue元件。 vue-cli3已經為我們安裝了是支援class和裝飾器的模組vue-property-decorator,當然想自己配置的朋友也可以通過webpack自己配置,無限可能,我也會在後面推出關於webpack的文章,教大家如何玩轉webpack4.0。

使用class方式建立元件和傳統的方式有點區別:1.一般我們定義data作為資料來源,在class中我們可以直接定義屬性,即可作為初始資料;2.vue例項方法一般定義在methods中,用類元件時,可以直接使用元件方法。 最後,我們可以用vuex提供的commit和dispatch來觸發我們狀態的變化,至此,一個class版的vue元件就寫好啦,如有不懂的地方或者文章沒有考慮到的地方,歡迎隨時指出。如果想了解更多前端知識,交流前端經驗,歡迎加入我們的學習交流群。

vue高階進階系列——用typescript玩轉vue和vuex

接下來即將推出的文章: 1.玩轉webpack4.0 2.typescript實用知梳理 3.react+redux+redux+trunk+immutable實戰總結

相關文章