參考:
官方文檔
安裝? npm install -D vuex-module-decorators
安裝成功后就可以使用啦,先看一個完整案例
// store/modules/passenger.ts
import {Module,VuexModule,Mutation,Action,getModule,} from 'vuex-module-decorators';
import store from '@/store';
type User = { username: string; password: string; }
// dynamic: true: 動態(tài)創(chuàng)建動態(tài)模塊,即new Vuex.Store({})里面不用注冊的.空著就行,
// store,當(dāng)前模塊注冊到store上.也可以寫在getModule上,即getModule(PassengerStore,store)
// namespaced: true, name: 'passenger' 命名空間
@Module({
? name: 'passenger', dynamic: true, namespaced: true, store,
})
export default class PassengerStore extends VuexModule {
? // state => 要public不然外面調(diào)用不到
? public loginInfo: User[] = [];
? // getter
? get userNumber(): number {
? ? return this.loginInfo.length;
? }
? @Mutation
? USERINFO(user: User): void {
? ? console.log(user);
? ? this.loginInfo.push(user);
? }
? // commit的兩種調(diào)用方式,第一種,Action后面的括號里面添加commit,然后return的結(jié)果就是USERINFO的參數(shù)
? @Action({ commit: 'USERINFO' })
? getZhangsan(): User {
? ? return { username: '張三', password: 'zhangsan' };
? }
? // 第二種,直接this.USERINFO調(diào)用;
? @Action
? getLisi(): void {
? ? const user = { username: '李四', password: 'lisi' };
? ? this.context.commit('USERINFO', user); // commit調(diào)用
? ? // this.USERINFO(user); // 直接調(diào)用
? }
}
// 使用getModule: 對類型安全的訪問
export const PassengerStoreModule = getModule(PassengerStore);
// sotre/index.ts
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
export default new Vuex.Store({ }); // 由于passenger->dynamic: true: 是動態(tài)創(chuàng)建動態(tài)模塊,所以不需要再次注冊
index.vue頁面使用
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import { PassengerStoreModule } from '@/store/modules/passenger';
@Component
export default class IndexPage extends Vue {
? ? created() {
? ? ? ? console.log(PassengerStoreModule.loginInfo); // state
? ? ? ? console.log(PassengerStoreModule.userNumber); // getter
? ? ? ? PassengerStoreModule.getZhangsan(); // actions
? ? ? ? PassengerStoreModule.getLisi(); // actions
? ? }
}
</script>
上面的案例是一個,使用了動態(tài)注冊,下面我們詳細(xì)說下,具體的使用
@Component state getter
@Mutations
@Actions
@MutationsActions
getModule
動態(tài)模塊
import { Module, VuexModule } from 'vuex-module-decorators'
@Module
export default class Vehicle extends VuexModule {
? wheels = 2
}
等同于下面的代碼
export default {
? state: { wheels: 2 }
}
getter
import { Module, VuexModule } from 'vuex-module-decorators'
@Module
export default class Vehicle extends VuexModule {
? wheels = 2
? get axles() {
? ? return this.wheels / 2
? }
}
等同于下面的代碼
export default {
? state: { wheels: 2 },
? getters: {
? ? axles: (state) => state.wheels / 2
? }
}
@Mutations
import { Module, VuexModule, Mutation } from 'vuex-module-decorators'
@Module
export default class Vehicle extends VuexModule {
? wheels = 2
? @Mutation
? puncture(n: number) {
? ? this.wheels = this.wheels - n
? }
}
等同于下面的代碼
export default {
? state: { wheels: 2 },
? mutations: {
? ? puncture: (state, payload) => {
? ? ? state.wheels = state.wheels - payload
? ? }
? }
}
@Actions
import { Module, VuexModule, Mutation, Action } from 'vuex-module-decorators'
import { get } from 'request'
@Module
export default class Vehicle extends VuexModule {
? wheels = 2
? @Mutation
? addWheel(n: number) {
? ? this.wheels = this.wheels + n
? }
? @Action
? async fetchNewWheels(wheelStore: string) {
? ? const wheels = await get(wheelStore)
? ? this.context.commit('addWheel', wheels)
? }
}
等同于下面的代碼
const request = require('request')
export default {
? state: { wheels: 2 },
? mutations: {
? ? addWheel: (state, payload) => {
? ? ? state.wheels = state.wheels + payload
? ? }
? },
? actions: {
? ? fetchNewWheels: async (context, payload) => {
? ? ? const wheels = await request.get(payload)
? ? ? context.commit('addWheel', wheels)
? ? }
? }
}
@MutationAction
在vuex中是要通過commit來更改state中的數(shù)據(jù).在vuex-module-decorators中有MutationAction修飾器,可以直接修改state數(shù)據(jù).
export default class PassengerStore extends VuexModule {
? public username = '';
? public password = '';
? //'username'和'password'被返回的對象替換,
? //格式必須為`{username:...,password:...}`
? @MutationAction({ mutate: ['username', 'password'] })
? async setPassenger(name: string) {
? ? const response: any = await request(name); // 接口返回 [{name:'張三',password:'123456'}]
? ? // 此處返回值必須和上面mutate后面的名稱保持一致;
? ? return {
? ? ? username: response[0].name,
? ? ? password: response[0].password,
? ? };
? }
}
// index.vue中使用
<template>
? ? <div class="">
? ? ? ? 用戶名:{{PassengerStoreModule.username}}<br/>
? ? ? ? 密碼:{{PassengerStoreModule.password}}<br/>
? ? ? ? <button @click="getPassenger()">getPassenger</button>
? ? </div>
</template>
...
@Component
export default class IndexPage extends Vue {
? ? private PassengerStoreModule: any = PassengerStoreModule;
? ? getPassenger() {
? ? ? ? PassengerStoreModule.setPassenger('西施');
? ? }
}
// 運(yùn)行過后,點(diǎn)擊getPassenger按鈕,用戶名和密碼會發(fā)生變化哦
getModule:創(chuàng)建類型安全的訪問
傳統(tǒng)是需要注冊到的new?Vuex.Store上,然后通過this$store訪問,使用getModule訪問類型更加安全,
可以再module上使用store模塊,然后getModule(模塊名)
也可以getModule(模塊名,this.$store)的形式
import { Module, VuexModule, getModule } from 'vuex-module-decorators'
import store from '@/store'
// 1. module上使用store
@Module({ dynamic: true, store, name: 'mymod' })
class MyModule extends VuexModule {
? someField: number = 10
}
const myMod = getModule(MyModule)
myMod.someField //works
myMod.someOtherField //Typescript will error, as field doesn't exist
// 2. module上不使用store,? getModule使用store
@Module({ dynamic: true, name: 'mymod' })
class MyModule extends VuexModule {
? someField: number = 10
}
const myMod = getModule(MyModule,store)
...