vuex-module-decorators详解

参考:

官方文档

vuex-module-decorators

安装  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: 动态创建动态模块,即new Vuex.Store({})里面不用注册的.空着就行,

// store,当前模块注册到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不然外面调用不到

  public loginInfo: User[] = [];

  // getter

  get userNumber(): number {

    return this.loginInfo.length;

  }

  @Mutation

  USERINFO(user: User): void {

    console.log(user);

    this.loginInfo.push(user);

  }

  // commit的两种调用方式,第一种,Action后面的括号里面添加commit,然后return的结果就是USERINFO的参数

  @Action({ commit: 'USERINFO' })

  getZhangsan(): User {

    return { username: '张三', password: 'zhangsan' };

  }

  // 第二种,直接this.USERINFO调用;

  @Action

  getLisi(): void {

    const user = { username: '李四', password: 'lisi' };

    this.context.commit('USERINFO', user); // commit调用

    // this.USERINFO(user); // 直接调用

  }

}

// 使用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: 是动态创建动态模块,所以不需要再次注册

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>

上面的案例是一个,使用了动态注册,下面我们详细说下,具体的使用

@Component state getter

@Mutations

@Actions

@MutationsActions

getModule

动态模块

state:

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中的数据.在vuex-module-decorators中有MutationAction修饰器,可以直接修改state数据.

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('西施');

    }

}

// 运行过后,点击getPassenger按钮,用户名和密码会发生变化哦

getModule:创建类型安全的访问

传统是需要注册到的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)

...

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容