likes
comments
collection
share

Vuex4 TypeScript 类型 Api介绍及在Vue3 中使用

作者站长头像
站长
· 阅读数 14

本文介绍TypeScript类型的Vuex4中的一些Api。并编写了一个Vue3 + TypeScript使用Vuex4的案例。

Vuex4 相关Api介绍

createStore<S>

createStore的作用是创建一个store实例。createStore方法接收一个StoreOptions<S>类型的参数,并返回一个Store<S>。如下图所示: Vuex4 TypeScript 类型 Api介绍及在Vue3 中使用

StoreOptions<S>

StoreOptions是一个描述Store的接口,里面包含了我们熟悉的statemutationsactionsgettersmodules。如下图所示: Vuex4 TypeScript 类型 Api介绍及在Vue3 中使用

state

状态对象。

  • 类型:对象或函数,如果传入的是一个函数,函返回的对象会被用作state

getters

获取state数据的方法集对象。

  • 类型:GetterTree<S, R>:描述getter方法集接口
GetterTree<S, R>

描述getter方法集接口。这个接口定义了实现他的对象属性为string类型,值为Getter<S, R>类型。 Vuex4 TypeScript 类型 Api介绍及在Vue3 中使用

Getter<S, R>

描述getter方法格式的类型。方法的参数和返回值如下

  • 参数: state: S, getters: any, rootState: R, rootGetters: any
  • 返回值: any Vuex4 TypeScript 类型 Api介绍及在Vue3 中使用

mutations

变更state的方法集对象。

  • 类型: MutationTree<S>: 描述变更方法集接口
MutationTree<S>

描述变更方法集接口。

Vuex4 TypeScript 类型 Api介绍及在Vue3 中使用

Mutation<S>

描述变更方法格式的类型。方法的参数和返回值如下

  • 参数:state: S, payload?: any
  • 返回值:any Vuex4 TypeScript 类型 Api介绍及在Vue3 中使用

actions

actions是类似于mutations,不同的是mutations中的方法是同步的,actions中的方法可以是异步的。

Action 提交的是 mutation,而不是直接变更状态。

  • 类型:ActionTree<S, S>: 描述action方法集接口
ActionTree<S, S>

描述action方法集接口。

Vuex4 TypeScript 类型 Api介绍及在Vue3 中使用

Action<S, R>

Action<S, R>既可以是ActionHandler<S, R>类型,也可以是ActionObject<S, R>类型 Vuex4 TypeScript 类型 Api介绍及在Vue3 中使用

ActionHandler<S, R>ActionObject<S, R>类型定义如下: Vuex4 TypeScript 类型 Api介绍及在Vue3 中使用

modules

放置Store模块的对象

  • 类型:ModuleTree<R>
ModuleTree<R>

描述Module对象集接口 Vuex4 TypeScript 类型 Api介绍及在Vue3 中使用

Module<any, R>

描述模块的接口

Vuex4 TypeScript 类型 Api介绍及在Vue3 中使用

Demo

这个Demo包含在主文件中管理用户信息和在字典模块中管理字典

store/index.ts文件。store/index.ts管理用户信息的state, 内容如下:

import { createStore } from "vuex";
import { getUserInfoById } from "@/api/user";  // 发起请求获取用户信息
import DictStoreModule from "./modules/DictStore";

interface IUserInfo {
  id: string;
  name: string;
  sex: string;
  birtyDay: Date;
}

interface IUserIngoStore {
  [key: string]: IUserInfo | undefined;
}

const userInfo: IUserInfo | undefined = undefined;

export default createStore<IUserIngoStore>({
  state: { userInfo },
  getters: {
    // 这里只需要state参数,getters、rootState、rootGetters参数用不到可以不接收
    getUserInfo: (state): IUserInfo | undefined => {
      return state.userInfo;
    },
  },
  mutations: {
    setUserInfo(state, payload: IUserInfo): void {
      state.userInfo = payload;
    },
    delUserInfo(state): void {
      state.userInfo = undefined;
    },
  },
  actions: {
    fetchUserInfo: async (context, payload: string): Promise<void> => {
      const userInfoData = await getUserInfoById(payload);
      context.commit("setUserInfo", userInfoData);
    },
  },
  modules: { DictStoreModule },
});

store/modules/DictStore.ts管理字典的state, 内容如下:

import { getDictByName } from "@/api/dict";
import { Module } from "vuex";

export interface IDictItem {
  id: string;
  lable: string;
  value: string | number | boolean;
}

export const dicts = new Map<string, IDictItem[]>();

dicts.set("sex", [
  { id: "1", lable: "男", value: "1" },
  { id: "2", lable: "女", value: "2" },
]);

interface IDict {
  [key: string]: Map<string, IDictItem[]>;
}

const DictStoreModule: Module<IDict, any> = {
  state: { dicts },
  getters: {
    getDict:
      (state) =>
      (key: string): IDictItem[] | undefined => {
        const dict = state.dicts.get(key);
        return dict;
      },
  },
  mutations: {
    setDict(state, payload: Map<string, IDictItem[]>): void {
      payload.forEach((v, k) => {
        state.dicts.set(k, v);
      });
    },
    delDict(state, payload: string): boolean {
      return state.dicts.delete(payload);
    },
    clearAll(state: IDict): void {
      return state.dicts.clear();
    },
  },
  actions: {
    fetchDict: async (context, payload: string): Promise<void> => {
      const data = await getDictByName(payload);
      const dict = new Map<string, IDictItem[]>();
      dict.set(payload, data);
      context.commit("setDict", dict);
    },
  },
};

export default DictStoreModule;

使用

Vue3组合式API中可以通过调用 useStore函数,在setup钩子函数中访问store。这与在组件中使用选项式API访问 this.$store是等效的。

import { useStore } from "vuex";

const store = useStore();
// 调用在字典模块的getters中定义的getDict方法
const dictData = store.getters.getDict方法(dictName);

全局注册方法

编写调用字典store的方法,并全局混入以便在使用时直接调用。

  1. 编写插件,在插件中混入混入编写的方法
import { IDictItem } from "@/store/modules/DictStore";
import { App } from "vue";
import { useStore } from "vuex";

const DictInstall = {
  install: (app: App): App<any> => {
    app.mixin({
      methods: {
        dictData: (dictName: string): IDictItem[] | undefined => {
          const store = useStore();
          const dictData = store.getters.getDict(dictName);
          if (!dictData) {
            store.dispatch("fetchDict", dictName);
          }
          return dictData;
        },
        dictDataLable: (
          dictName: string,
          dictValue: string | number | boolean
        ): string | undefined => {
          const store = useStore();
          const dictData = store.getters.getDict(dictName);
          if (!dictData) {
            store.dispatch("fetchDict", dictName);
          }
          if (dictData) {
            const dictItem = dictData.find(
              (d: IDictItem) => d.value === dictValue
            );
            if (dictItem) {
              return dictItem.lable;
            }
          }
          return undefined;
        },
      },
    });

    return app;
  },
};

export default DictInstall;

  1. 全局注册插件
import DictInstall from "./plugins/DictPlugin";

const app = createApp(App);
app.use(DictInstall).use(store).use(router).use(Antd).mount("#app");
  1. 使用全局混入的方法
<template>
  <div>dict: {{ dictData("sex") }}</div>
  <div>dictLable: {{ dictDataLable("sex", "1") }}</div>
</template>

<script setup ts>
</script>

<style lang="scss" scoped></style>
  1. 效果

Vuex4 TypeScript 类型 Api介绍及在Vue3 中使用