如何使用 vue + typescript 編寫頁面 ( vuex裝飾器補充部分--store裝飾器 )

董輝輝發表於2019-02-19

本章是對上一章 如何使用 vue + typescript 編寫頁面 ( vuex裝飾器部分 )的補充 ,感謝 @慕容寒江 的提出建議

在使用store裝飾器之前,先過一下傳統的store用法吧

export default  {
    namespaced:true,
    state:{
        foo:""
    },
    getters:{
        getFoo(state){ return state.foo}
    },
    mutations:{
        setFooSync(state,payload){
            state.foo = payload
        }
    },
    actions:{
        setFoo({commit},payload){
            commot("getFoo",payload)
        }
    }
}
複製程式碼

然後開始使用vuex-module-decorators

import {
Module,
VuexModule, 
Mutation, 
Action, 
MutationAction, 
getModule } from 'vuex-module-decorators'
複製程式碼

1. VuexModule 用於基本屬性

export default class TestModule extends VuexModule { }
複製程式碼

VuexModule 提供了一些基本屬性,包括namespaced,state,getters,modules,mutations,actions,context 其中context則會在接下來的程式碼中使用到

2. @Module 標記當前為module

@Module
export default class TestModule extends VuexModule {
    /* 這裡代表的就是state裡面的狀態 */
    inlineState = "";
    /* 這裡就是 getters 裡面的內容*/
    get named(){
        return 1;
    }
}
複製程式碼

module本身有幾種可以配置的屬性

  • namespaced:boolean 啟/停用 分模組
  • stateFactory:boolean 狀態工廠[我也不知道幹什麼的,有知道的可以留言]
  • dynamic:boolean 在store建立之後,再新增到store中。 開啟dynamic之後必須提供下面的屬性
  • name:string 指定模組名稱
  • store:Vuex.Store實體 提供初始的store

dynamic 模式

動態模式為反向注入store。

常規下是

export default new Vuex.Store({
    modules:{  TestModule }
})
複製程式碼

開啟後為

// store.ts
export default new Vuex.Store({
    modules:{  /* 其餘的store */ }
})
複製程式碼
import store from './store'
@Module({
    dynamic:true,
    name: "TestModule", 
    store
})
export default class TestModule extends VuexModule { }
// 在需要引用的地方單獨引用該store檔案即可注入。
// 好處:靈活使用,僅僅在需要引入的地方才注入到store中去
// 缺點:需要單獨引入檔案
複製程式碼

3. @Mutation 標註為mutation

@Module
export default class TestModule extends VuexModule {
    inlineState = "";
    @Mutation
    setInlineStateSync(inlineState:string){
        this.inlineState = inlineState;
    }
}
複製程式碼

4. @Action 標註為action

用法和@Emit很相似

@Module
export default class TestModule extends VuexModule {

    @Action({ commit: 'setInlineStateSync' })
    setInlineState(inlineState:string){
        /*這裡使用自動提交*/
        return inlineState;
    }
    @Action
    setInlineStateContext(inlineState:string){
        /* 這裡使用手動提交 */
        this.context.commit("setInlineStateSync",inlineState)
    }
}
複製程式碼

5. @MutationAction

這個屬性可以直接對映屬性,

  • mutate 提供屬性列表
@Module
export default class TestModule extends VuexModule {
    
    foo = "";
    doo = "";
    
    @MutationAction({mutate:["foo","doo"]/*提供需要對映的屬性列表*/})
    async setMutationAction(payload:{foo:string,doo:string} /* 傳入的payload物件屬性需要和mutate的名稱一致*/){
        /* 這裡如果有返回,則必須返回一個Promise<{foo:string,doo:string}>型別*/
        /* 但是在使用時,則有很奇葩的事情*/
        /* 如果對映為Mutation [ @Mutation("TestModule/setMutationAction") ],則不會執行函式本身, 使用傳入的值作為結果*/
        /* 如果對映為Action [ @Action("TestModule/setMutationAction") ],會執行函式本身並且得到的返回值為結果 */
    }
}

複製程式碼

6. getModule 得到一個型別安全的store,module必須提供name屬性

@Module({ name : "tm" })
export default class TestModule extends VuexModule {
    
}
複製程式碼

常規,需要提供store,即:

getModule(TestModule,this.$store).inlineState  // "inlineState value"
複製程式碼

開啟dynamic時,不需要提供store,因為module本身已經注入store。

 getModule(TestModule).inlineState  // "inlineState value"
複製程式碼

更多內容參照vuex-module-decorators 或者 github:vuex-module-decorators

相關文章