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

Vue

背景

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