问题描述:
系统登录成功需要将后台返回的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();
})
最终持久化成功: