vue3 setup script+Typescript实战用法(三)——vuex store
vuex对ts的支持非常差,不设置的话,ts编译不通过。听说pinia对ts的支持非常好,不过我没用过,还是用官方的状态管理器把。
我看官方是用injectionkey的方式进行注入,但是我自己测试了之后发现,不用这种方法,传入泛型也可以,所以我将演示这种比较简单的方法。
项目结构,只需要3个ts文件
├─ store
│ ├─ index.ts
│ └─ modules
│ └─ home.ts
├─ type
│ └─ global.ts
在store中定义一些数据
//store/index.ts
import { createStore } from 'vuex'
import homeModule, { homeState } from './modules/home'
export default createStore<rootState>({
state: {
count: 20,
},
modules: {
homeModule,
},
getters: {
double(state) {
const double = state.count * 2
return double
},
},
})
export interface rootState {
count: number
}
export interface Modules extends rootState {
homeModule: homeState
aboutModule: aboutState
}
vuex在全局变量这块和modules这块的支持不是很友好。比如在模板字符串中是无法识别出$store
然后要去global.ts中给vuex的模块做一个扩展
//global.ts
import type { Modules } from '../store'
import { Store } from 'vuex'
declare module '@vue/runtime-core' {
interface ComponentCustomProperties {
$store: Store<Modules>
}
}
接着到home.ts中定义一下模块
//home.ts
import { Module } from 'vuex'
import { rootState } from '..'
export interface homeState {
index: number
}
const homeModule: Module<homeState, rootState> = {
namespaced: true,
state: {
index: 27,
},
mutations: {
add(state) {
state.index++
},
},
}
export default homeModule
定义好后,一定要关闭vscode重启!因为ts的延迟实在是太慢了,一直飘红还没缓过来。搞得我一度怀疑是我哪里写错了。
解释一下上面的代码: 定义好state的数据类型rootState,然后传入createStore的泛型中,state就能代码提示了。但是modules模块还是不能代码提示。
在modules/home.ts中定义模块homeModule,homeModule需要定义好数据类型Module<homeState, rootState>,一个是自己的state类型homeState,另一个是根状态的数据类型rootState。
在index.ts中定义好模块modules的数据类型Modules与根状态的数据类型rootState合并,并且暴露出去。
在其他地方使用的时候,只要传入这个Modules泛型,就能得到modules的代码提示了。
//App.vue
<template>
<h1>{{ $store.state.homeModule.index }}</h1>
</template>
//App.vue
<script setup lang="ts">
import { useStore } from 'vuex'
import { Modules } from './store'
const store = useStore<Modules>()
store.state.homeModule
</script>
getters的代码提示我还在研究
经本人5次测试,5次都能很好代码提示,如果你的不能代码提示,请查看自己的代码是否打错了,并且重启vscode。
转载自:https://juejin.cn/post/7012917202298863624