美文网首页Vue3vue
vue3.x+vuex4.x+ts store类型定义

vue3.x+vuex4.x+ts store类型定义

作者: 无疆wj | 来源:发表于2021-12-24 11:42 被阅读0次

    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); // 正常
    

    相关文章

      网友评论

        本文标题:vue3.x+vuex4.x+ts store类型定义

        本文链接:https://www.haomeiwen.com/subject/gadlqrtx.html