前端数据状态管理

Pinia 状态管理

状态管理方案

框架使用 Pinia 进行数据状态管理,代码位置:/src/stores。详细信息请参考 Pinia 官网

历史版本说明

旧版本使用 Vuex Module 模块化管理,相关文档:Vuex 3.x 官网

全局引入

页面模块已做全局自动引入,代码位置:/@/store/index.ts

Vite 动态导入

使用 import.meta.globEager 实现模块的自动导入。

const modulesFiles = import.meta.globEager("./modules/*.ts");
const pathList: string[] = [];

for (const path in modulesFiles) {
  pathList.push(path);
}

const modules = pathList.reduce(
  (modules: { [x: string]: any }, modulePath: string) => {
    const moduleName = modulePath.replace(/^./modules/(.*).w+$/, "$1");
    const value = modulesFiles[modulePath];
    modules[moduleName] = value.default;
    return modules;
  },
  {}
);

定义接口

Interface 定义

/@/store/interface/index.ts 中定义数据结构接口,例如路由缓存列表 KeepAliveNamesState

// 路由缓存列表
export interface KeepAliveNamesState {
  keepAliveNames: Array<string>;
}

Interface 使用

/@/store/modules/ 目录下新增模块文件,例如 keepAliveNames.ts

模块命名空间

需要开启 namespaced: true,文件名称即为模块名称。详见 Vuex Module 命名空间

1import { Module } from "vuex";
2// 此处加上 `.ts` 后缀报错,具体原因不详
3import { KeepAliveNamesState, RootStateTypes } from "/@/store/interface/index";
4
5const keepAliveNamesModule: Module<KeepAliveNamesState, RootStateTypes> = {
6  namespaced: true,
7  state: {
8    keepAliveNames: [],
9  },
10  mutations: {
11    // 设置路由缓存(name字段)
12    getCacheKeepAlive(state: any, data: Array<string>) {
13      state.keepAliveNames = data;
14    },
15  },
16  actions: {
17    // 设置路由缓存(name字段)
18    async setCacheKeepAlive({ commit }, data: Array<string>) {
19      commit("getCacheKeepAlive", data);
20    },
21  },
22};
23
24export default keepAliveNamesModule;

定义模块

/@/store/modules/ 目录下新增模块文件(如 keepAliveNames.ts),并定义 mutationsactions 方法。

使用模块

在 TypeScript 中使用

.ts 文件中导入 store 并使用 dispatch 或 commit 方法。

import { store } from "/@/store/index.ts";

// dispatch
store.dispatch("keepAliveNames/setCacheKeepAlive", cacheList);

// 或者 commit
// store.commit("keepAliveNames/getCacheKeepAlive", cacheList);

在 Vue 组件中使用

.vue 文件中通过 useStore 访问状态管理。

1<template>
2  <div v-if="getThemeConfig.isLockScreen">在 .vue 中使用</div>
3</template>
4
5<script lang="ts">
6  import { computed, defineComponent } from "vue";
7  import { useStore } from "/@/store/index";
8  export default defineComponent({
9    name: "app",
10    setup() {
11      const store = useStore();
12      // 获取布局配置信息
13      const getThemeConfig = computed(() => {
14        return store.state.themeConfig.themeConfig;
15      });
16    },
17  });
18</script>