vue3.x+vuex4.x+ts store类型定义
2021-12-24 本文已影响0人
无疆wj
vue3.0+vuex+ts实现数据模块化及类型化
跟着这篇文章自己实现一遍,并做了一点扩展,记录一下
引入vuex4.x
跟着vuex官网配置初始的store
创建store目录和vuex.d.ts
store
--index.ts // store定义文件
--type.ts // store类型定义文件
vuex.d.ts
store/type.ts
/**
* root层state类型定义
*/
export interface TypeRootState {
count: number;
}
store/index.ts
import { App, InjectionKey } from "vue";
import { createStore, useStore as baseUseStore, Store } from "vuex";
import { TypeRootState } from "./type";
// 创建一个新的 store 实例
const store = createStore<TypeRootState>({
state() {
return {
count: 0,
};
},
mutations: {
increment(state) {
state.count++;
},
},
});
export default store;
// 定义 injection key
const key: InjectionKey<Store<TypeRootState>> = Symbol();
// 定义自己的 `useStore` 组合式函数
export function useStore() {
return baseUseStore(key);
}
export const setupStore = (app: App) => {
app.use(store, key);
};
vuex.d.ts
// vuex.d.ts
import { ComponentCustomProperties } from "vue";
import { Store } from "vuex";
import { TypeRootState } from "@/store/type";
declare module "@vue/runtime-core" {
// 为 `this.$store` 提供类型声明
interface ComponentCustomProperties {
$store: Store<TypeRootState>;
}
}
main.ts引入
// main.ts
import { createApp } from "vue";
import App from "./App.vue";
import { setupStore } from "./store";
const app = createApp(App);
setupStore(app); // 安装store
app.mount("#app");
至此vuex可以初步使用
<template>
<div>测试页面</div>
</template>
<script setup lang="ts">
import { useStore } from "@/store";
const store = useStore();
console.log(store.state.count); // 正常
</script>
<script lang="ts">
import { defineComponent } from "vue";
export default defineComponent({
mounted() {
console.log(this.$store.state.count); // 正常
},
});
</script>
使用模块(module)
创建文件
store
--modules // 模块目录
--app.ts
index.ts
type.ts
store/modules/app.ts
import { Module } from "vuex";
import { TypeRootState } from "@/store/type";
export interface TypeModuleStateApp {
appCount: number;
}
export const moduleApp: Module<TypeModuleStateApp, TypeRootState> = {
state: () => ({
appCount: 0,
}),
};
store/type.ts
引入模块state类型TypeModuleStateApp
, 声明并导出所有state类型定义TypeAllState
/**
* 模块state类型引入
*/
import { TypeModuleStateApp } from "./modules/app";
/**
* vuex所有state类型定义集成
*/
export interface TypeAllState extends TypeRootState {
moduleApp: TypeModuleStateApp;
}
store/index.ts
引入模块和TypeAllState
; 给baseUseStore
传入泛型TypeAllState
import { TypeRootState, TypeAllState } from "./type";
import { moduleApp } from "./modules/app";
// 创建一个新的 store 实例
const store = createStore<TypeRootState>({
modules: {
moduleApp: moduleApp,
},
});
export function useStore<T = TypeAllState>() {
return baseUseStore<T>(key);
}
vuex.d.ts
TypeRootState
改为 TypeAllState
import { TypeAllState } from "@/store/type";
declare module "@vue/runtime-core" {
// 为 `this.$store` 提供类型声明
interface ComponentCustomProperties {
$store: Store<TypeAllState>;
}
}
至此可以正常使用模块(module)
<template>
<div>测试页面</div>
</template>
<script setup lang="ts">
import { useStore } from "@/store";
const store = useStore();
console.log(store.state.count); // 正常
console.log(store.state.moduleApp.appCount); // 正常
</script>
<script lang="ts">
import { defineComponent } from "vue";
export default defineComponent({
mounted() {
console.log(this.$store.state.count); // 正常
console.log(this.$store.state.moduleApp.appCount); // 正常
},
});
</script>
扩展: 在***.ts
文件中使用store模块
store/index.ts;
声明自定义的store类型TypeCustomStore
(继承TypeRootState
),修改state
的类型;
强制修改导出的store的类型;
interface TypeCustomStore extends Store<TypeRootState> {
state: TypeAllState;
}
export default store as unknown as TypeCustomStore;
然后就可以在***.ts
中正常使用模块了
import store from "@/store";
console.log(store.state.moduleApp.appCount); // 正常