Store For Pinia使用

持久化

目前暂时没有持久化的必要!!!

从你提供的日志来看,刷新页面后,Pinia Store 的状态似乎被重置了。这通常是因为在刷新页面时,应用的 JavaScript 会重新加载,导致状态存储在内存中的 Store 数据丢失。为了保持登录状态和其他用户信息,通常会将一些关键数据存储在持久化存储中(例如 localStorage 或 sessionStorage),并在应用重新加载时从存储中恢复这些数据。

可以使用 pinia-plugin-persist 插件来实现这一功能。以下是如何设置和使用 pinia-plugin-persist 的步骤:

1. 安装 pinia-plugin-persist

首先,你需要安装 pinia-plugin-persist

1
npm install pinia-plugin-persist

2. 配置 pinia-plugin-persist

在你的 Pinia 配置中添加这个插件:

1
2
3
4
5
6
7
import { createPinia } from 'pinia';
import piniaPluginPersist from 'pinia-plugin-persist';

const pinia = createPinia();
pinia.use(piniaPluginPersist);

export default pinia;

3. 更新 userStore 以启用持久化

在你的 userStore 中启用持久化:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import { defineStore } from 'pinia';

export const useUserStore = defineStore({
  id: 'userStore',
  state: () => ({
    roles: [] as string[],
    permissions: [] as string[],
    hasInitDynamicRoute: false,
  }),
  actions: {
    async getUserProfile() {
      const data = await userApi.getUserProfile();
      this.roles = data.roles;
      this.permissions = data.permissions;
    },
    setHasInitDynamicRoute() {
      this.hasInitDynamicRoute = true;
    },
    resetDynamicRoute() {
      this.hasInitDynamicRoute = false;
    },
    logout() {
      this.resetDynamicRoute();
      this.roles = [];
      this.permissions = [];
      localStorage.removeItem(APP_TOKEN_KEY);
    }
  },
  persist: {
    enabled: true,
    strategies: [
      {
        key: 'userStore',
        storage: localStorage,
      }
    ]
  }
});

4. 初始化 Pinia 并挂载到 Vue 应用

在你的 main.ts 或 main.js 文件中初始化 Pinia 并挂载到 Vue 应用:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
import { createApp } from 'vue';
import App from './App.vue';
import router from './router';
import pinia from './stores'; // 确保引入的是配置了持久化插件的 pinia 实例

const app = createApp(App);

app.use(router);
app.use(pinia);

app.mount('#app');

5. 确保在导航守卫中处理持久化数据

在导航守卫中,确保从 Store 中获取用户数据和权限:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
import { APP_TOKEN_KEY } from '@/enums/AppConfigEnum';
import { log } from '@/plugins/logger';
import router from '@/router';
import { useUserStore } from '@/store/userStore';
import { RouteLocationNormalized } from 'vue-router';

export function configDynamicRouting() {
  router.beforeEach(async (to: RouteLocationNormalized, from: RouteLocationNormalized) => {
    log('to.path=%s, to.fullPath=%s, to.hash=, to.matched=%s, to.meta=%s, to.name=%s, to.params=%s, to.query=%s, to.redirectedFrom=%s,',
      to.path, to.fullPath, to.hash, to.matched, to.meta, to.name, to.params, to.query, to.redirectedFrom);

    log('from.path=%s, from.fullPath=%s, from.hash=, from.matched=%s, from.meta=%s, from.name=%s, from.params=%s, from.query=%s, from.redirectedFrom=%s,',
      from.path, from.fullPath, from.hash, from.matched, from.meta, from.name, from.params, from.query, from.redirectedFrom);

    const token = localStorage.getItem(APP_TOKEN_KEY);

    if (!token) {
      if (to.name === 'Login') {
        log("未登录,访问登录页");
        return true;
      } else if (to.matched.length !== 0) {
        log("未登录,访问其它页 + 匹配成功, to.matched.length=%s", to.matched.length);
        return { name: 'Login' };
      } else if (to.matched.length === 0) {
        log("未登录,访问其它页 + 匹配失败");
        return { name: '404' };
      }
    } else {
      log("已登录....");

      const userStore = useUserStore();
      const { hasInitDynamicRoute, roles, permissions } = storeToRefs(userStore);

      if (to.name === 'Login') {
        if (hasInitDynamicRoute.value) {
          log("已登录 + 已初始化动态路由,访问登录页");
          return { path: '/' };
        }
      }

      if (!permissions.value.length) {
        log("已登录 + 权限缓存为空");
        try {
          await userStore.getUserProfile();
          userStore.setHasInitDynamicRoute();
        } catch (error) {
          log("error %s", error);
          return { name: 'Login' };
        }
        return { ...to, replace: true };
      } else if (!hasInitDynamicRoute.value) {
        log("已登录 + 权限缓存有值 + 未设置动态路由");
        permissions.value.forEach(route => {
          if (!router.hasRoute(route.name)) {
            router.addRoute(route);
            log('动态添加路由: %s', route.name);
          }
        });
        userStore.setHasInitDynamicRoute();
        return { ...to, replace: true };
      }
      log("已登录 + 权限缓存有值 + 已设置动态路由");
      return true;
    }
  });
}

这样设置后,当你刷新页面时,Pinia Store 会从 localStorage 恢复状态,保持用户登录信息和权限数据。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计