使用vuex-ts-enhance提升vuex的使用体验

2,177 阅读2分钟

背景

vuexts支持并不友好, 我们定义了一堆state, 但是在使用mapXXX方法的时候并不知道有哪些namespace以及有哪些getters或者actions可以获取

vuex-ts-enhance, 借助ts的类型推导功能,在使用vuex时能提供state, actions, getters, mutationsdispatch的类型推导。解决了上述问题

简单使用

import { EnhanceStore } from 'vuex-ts-enhance'
import Vue from 'vue'
const state = {
    state: {
        // rootState
        root: {}
    },
    getters: {
        rootGet() { return 1 }
    },
    actions: {
        // rootActions
        setRoot(context, payload: string) {}
    },
    mutations: {
        setRoot(state, payload: string){}
    },
    modules: {
        sub: {
            namespaced: true,
            state: {
                substate: ''
            },
            actions: {
                setSubState(context, payload: number) {}
            },
            mutations: {
                setSubState(state, payload: number) {}
            },
            getters: {
                suGet() { return 2 }
            },
        }
    }
}
export const { mapGetters, store, mapActions, mapMutations, mapState } = s;
new Vue({
    store
})

这样就能完成初始化, 其实就是把state传入构造器中, 所返回的mapXXXX方法都带有类型推导, 并且能明确知道某个namespaced下有哪些数据或者方法能获取.

接下来看下vscode的提示

能看到mapGetters中有rootGet这一个rootGetters, 而且在使用时还能推导出其类型

同样能看到mapActions中有sub这一个namespace, 以及里面拥有setSubState这一个方法

当我们调用这个方法时也能有参数提示

而对于dispatch, 只能通过import进来使用

使用示例 dispatch(namespace, actions, payload) 或者 dispatch(rootActions, payload)

目前还不支持dispatchpayload的类型推导, 后续会增加

完整代码

<template>
  <div>
  </div>
</template>

<script lang="ts">
import Vue from 'vue';
import { mapGetters, mapActions, mapState, mapMutations } from './store'
export default Vue.extend({
  computed: {
    ...mapGetters(['rootGet']),
  },
  mounted() {
    this.rootGet // type number
    this.setSubState // type (payload: number) => Promise<void>
    dispatch('sub', 'setSubState', 1)
  },
  methods: {
    ...mapActions('sub', ['setSubState'])
  }
});
</script>

以上类型推导同时支持mapGetters, mapActions, mapState, mapMutations, dispatch

注意

  • 如果你使用typescript, 请不要把state定义成StoreOptions, 因为这样会让类型推导失效
const state: StoreOptions<any> = {} // don't do that
  • 如果你用js, 并且使用了jsdoc来定义来写, 请务必把context定义为any, 否则类型检查会失效
const state = {
  actions: {
    /**
     * @param {any} context
     * @param {string} payload
     */
    someActions(context, payload) {}
  }
}

End

以上代码是基于lant=ts下有的提示, 但如果是在lang=js下, vetur有时能提示类型, 又是又不能提示类型,详情见issue。暂且找不到问题所在。但mapXXXX方法的提示还依然生效, 因为他不依赖vetur