vuex-module-decorators食用方法

仓库地址:https://github.com/championswimmer/vuex-module-decorators

1、使用vuex-module-decorators前,当我们写一个store时,是这样的:

module.exports = {
  state: {
    num: []
  },
  getters: {
    getfunction: (state) => {
      return state.num
        .reduce((sum, cout) => {
          return sum + cout.comments.length
        }, 0)
    }
  },
  mutations: {
    update: (state, nums) => {
      state.nums = nums
    }
  },
  actions: {
    fetch: async (context) => {
      const payload = await get(api.update)
      context.commit('updatenums', payload)
    }
  }
}

2、当我们使用vuex-module-decorators时,你的store可以这样写:

import {VuexModule, Module} from 'vuex-module-decorators'
import {get} from 'axios'

@Module
export default class nums extends VuexModule {
     nums:[] //相当于state
	//get 相当于getters:
    get getfunction (): number {
        return nums.reduce((sum, cout) => {
            return sum + cout.comments.length
        }, 0)
    }
    //使用@Mutation装饰器,相当于Mutation:此时的this指向state
    @Mutation
    update(nums) {
        this.nums = nums
    }
	//相当于Action:函数内commit时:this.context.commit('mutationName',mutPayload)
    @Action({commit: 'updatenums'})
    async function fetch() {
        return await get(api.update)
    }
}

好处:
1、getmodule更安全,当你调用并不存在的state时,类型检查会提示你

const myMod = getModule(MyModule)
myMod.someField //works
myMod.someOtherField //Typescript will error, as field doesn't exist

2、Namespaced Modules、Dynamic Modules

3、详细使用方法

(我们可以与typescript同时使用)

state

import { Module, VuexModule } from 'vuex-module-decorators'

@Module
export default class Vehicle extends VuexModule {
  wheels = 2
}

类的所有属性都转换为state,等同于:

export default {
  state: {
    wheels: 2
  }
}

Getters

import { Module, VuexModule } from 'vuex-module-decorators'

@Module
export default class Vehicle extends VuexModule {
  wheels = 2
  get axles() {
    return this.wheels / 2
  }
}

所有的get函数都转换为 vuex getter,等同于:

export default {
  state: {
    wheels: 2
  },
  getters: {
    axles: (state) => state.wheels / 2
  }
}

我们还可以返回一个函数:

@Module
export default class Vehicle extends VuexModule {
  companies = []
  get company() {
    return (companyName: string) => { this.companies.find(company => company.name === companyName) };
  }
}

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
  }
}

用@Mutation 修饰的函数都被转换成Vuex 的mutations,相当于:

export default {
  state: {
    wheels: 2
  },
  mutations: {
    puncture: (state, payload) => {
      state.wheels = state.wheels - payload
    }
  }
}

⚠️

  • 使用@Mutation 装饰器进行装饰后,Mutations
    就会把this设置为state,当你想改变state时,例如:state.item++ 就是 this.item++

  • Mutation中不能使用异步函数,也不要将它们定义为箭头函数,因为在runtime会重新绑定,而箭头函数捕获this后无法改变

Action

mport { 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)
  }
}

所有用@Action 修饰的函数都会转换为vuex action,相当于:

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)
    }
  }
}

⚠️:

  • 由于this已经被绑定为state,当我们commit a mutation 时:可以直接:
this.context.commit('mutationName', mutPayload)
  • 这里会将函数包装为promise,适合异步函数,如果你想得到同步函数的结果,你需要放到Mutation中
  • 不要用箭头函数

命名空间

@Module({ namespaced: true, name: 'mm' })
class MyModule extends VuexModule {
  wheels = 2

  @Mutation
  incrWheels(extra: number) {
    this.wheels += extra
  }

  get axles() {
    return this.wheels / 2
  }
}

const store = new Vuex.Store({
  modules: {
    mm: MyModule
  }
})

⚠️

  • @Module中的name值, 必须要new store({modules: {}})中注册module name名称要一致.
  • this.store.dispatch(‘action’)调用需要转换为this.store.dispatch(‘name /action’)

动态module

1、首先我们要有一个store

// @/store/index.ts
import Vuex from 'vuex'

const store = new Vuex.Store({
  /*
  Ideally if all your modules are dynamic
  then your store is registered initially
  as a completely empty object
  */
})

2、将store传递给动态模块

// @/store/modules/MyModule.ts
import store from '@/store'
import {Module, VuexModule} from 'vuex-module-decorators'

@Module({dynamic: true, store, name: 'mm'})
export default class MyModule extends VuexModule {
  /*
  Your module definition as usual
  */
}

⚠️

  • 不支持动态 + 嵌套模块
  • 确保你导入的store是存在的

🌰一个完整的例子

store/modules/mytest.ts

import {
  VuexModule,
  Module,
  Mutation,
  Action,
  getModule,
} from 'vuex-module-decorators';
import * as API from '../../api/mytest';
import store from '../index';//这里导出store
export interface IGoodsItem {}
export interface ITestState {}
@Module({ dynamic: true, store, name: 'mytest' })
class App extends VuexModule implements ITestState {

  public mygoods?: IGoodsItem[];
  
  @Mutation
  setData(state: ITestState): void {
    Object.assign(this, state);
  }
  @Action({ rawError: true })
  async getMyapires(): Promise<ITestState> {
    const data = (await API.getMyapires()) || {};
    this.context.commit('setData', data);
    return data as ITestState;
  }
}
export const AppModule = getModule(App);

views/mytest.vue

<template>
  <div>将getModule引用到此页面</div>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import { AppModule } from '../store/modules/home';
@Component({})

export default class Mytest extends Vue {
  get myList() {
    return AppModule.mygoods;
  }
  mounted(): void {
    AppModule.getMyapires();
  }
}
</script>
<style lang="scss" scoped>
</style>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值