记录下Pinia持久化不生效问题

问题描述:
系统登录成功需要将后台返回的token持久化保存到localStorge中,这里使用pinia-plugin-persistedstate,在登陆成功后登录信息一直没有持久化到localStorge中。

代码如下:
1.配置持久化

import type { App } from 'vue'
import { createPinia } from 'pinia'
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'

const store = createPinia()
store.use(piniaPluginPersistedstate)

export const setupStore = (app: App<Element>) => {
  store.use(piniaPluginPersistedstate)
  app.use(store)
}

export { store }

2.配置userStore

import { defineStore } from 'pinia'
import { store } from "../index";

import router from "@/router/index";

interface UserState {
  tokenKey: string;
  token: string;
}

export const useUsersStore = defineStore("user", {
  state: (): UserState => ({
    tokenKey: "AccessToken",
    token: "",
  }),
  getters: {
    getTokenKey(): string {
      return this.tokenKey;
    },
    getToken(): string {
      return this.token;
    },
  },
  actions: {
    setTokenKey(tokenKey: string) {
      this.tokenKey = tokenKey;
    },
    setToken(token: string) {
      this.token = token;
    },
    reset() {
      this.setToken('');
      router.replace("/login");
    },
    logout() {
      this.reset();
    },
  },
  persist: true
});

export const useUserStoreWithOut = () => {
  return useUsersStore(store);
};

3.登录成功后持久化登录token

try {
      const loginResp = await loginApi(userlogin);
      if (loginResp && 200 === loginResp.code && loginResp.data) {
        userStore.setToken(loginResp.data.tokenValue);
        userStore.setTokenKey(loginResp.data.tokenName);
        let path = $route.query.redirect as string ?? "/";
        $router.push({ path })
      }
    } finally {
      loading.value = false;
    }

登录成功后查看控制台没发现持久化信息:

然而创建其他store持久化是没有任何问题,只有userStore没法持久化,最终定位到问题再vue router导航守卫,代码如下:

import router from "@/router";
import { useNProgress } from "@/hooks/useNProgress";
import { useUserStoreWithOut } from './store/module/user'

const { start, done } = useNProgress();
const userStore = useUserStoreWithOut();
// @ts-ignore
router.beforeEach((to, from, next) => {
    start();
    if (userStore.getToken) {
        if (to.path === '/login') {
            next({path: '/'});
        } else {
            // 是否有访问权限
        }
        next();
    } else {
        if (to.path === '/login') {
            next();
        } else {
            next({path: '/login', query: {'redirect': to.path}})
        }
    } 
});

router.afterEach((to) => {
  document.title = to?.meta?.title as string;  
  done();
})

这里userStore的创建应该放在beforeEach匿名方法中,代码如下:

import router from "@/router";
import { useNProgress } from "@/hooks/useNProgress";
import { useUserStoreWithOut } from './store/module/user'

const { start, done } = useNProgress();
// @ts-ignore
router.beforeEach((to, from, next) => {
    start();
    const userStore = useUserStoreWithOut();
    if (userStore.getToken) {
        if (to.path === '/login') {
            next({path: '/'});
        } else {
            // 是否有访问权限
        }
        next();
    } else {
        if (to.path === '/login') {
            next();
        } else {
            next({path: '/login', query: {'redirect': to.path}})
        }
    } 
});

router.afterEach((to) => {
  document.title = to?.meta?.title as string;  
  done();
})

最终持久化成功:

posted @ 2024-12-11 14:13  菜鸟的我先飞  阅读(1758)  评论(0)    收藏  举报