背景
vuex对ts支持并不友好, 我们定义了一堆state, 但是在使用mapXXX方法的时候并不知道有哪些namespace以及有哪些getters或者actions可以获取
而vuex-ts-enhance, 借助ts的类型推导功能,在使用vuex时能提供state, actions, getters, mutations和dispatch的类型推导。解决了上述问题
简单使用
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)
目前还不支持dispatch的payload的类型推导, 后续会增加
完整代码
<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