本章是對上一章 如何使用 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