Vue中Pinia Store登录状态刷新失效问题求助
问题:Pinia登录状态刷新后丢失,路由守卫拦截跳转
问题描述
登录后调用Pinia Store的setLoginValue将isLogged设为true并跳转到首页,页面刷新后路由守卫拒绝进入,控制台打印isLogged为false。
登录跳转时日志
🚀 ~ file: authGuard.js:5 ~ isAuth ~ isLogged: false auth.js:9 🚀 ~ file: auth.js:10 ~ setLoginValue ~ this.isLogged: false auth.js:11 🚀 ~ file: auth.js:10 ~ setLoginValue ~ this.isLogged: true authGuard.js:6 🚀 ~ file: authGuard.js:5 ~ isAuth ~ isLogged: true
刷新后日志
🚀 ~ file: authGuard.js:5 ~ isAuth ~ isLogged: false
相关代码
authGuard.js
import { storeToRefs } from "pinia"; import { useLogin } from "../stores/auth"; const isAuth = (to, from, next) => { const { isLogged } = storeToRefs(useLogin()); console.log("🚀 ~ file: authGuard.js:5 ~ isAuth ~ isLogged:", isLogged.value); isLogged.value ? next() : next({ name: "login" }); }; export default isAuth;
auth.js (store)
import { defineStore } from "pinia"; const useLogin = defineStore("login", { state: () => ({ isLogged: false, }), actions: { setLoginValue() { console.log("🚀 ~ file: auth.js:10 ~ setLoginValue ~ this.isLogged:", this.isLogged) this.isLogged = true; console.log("🚀 ~ file: auth.js:10 ~ setLoginValue ~ this.isLogged:", this.isLogged) }, }, }); export { useLogin };
LoginLayout.vue
<script setup> import { useRouter } from "vue-router"; import { useLogin } from "../stores/auth"; // Login Store const store = useLogin(); const { setLoginValue } = store; const router = useRouter(); const callback = (_) => { setLoginValue(); router.push({ name: "home" }); }; </script>
问题根源
Pinia的状态默认仅存储在浏览器内存中,页面刷新时内存数据会被清空,isLogged会重置为初始值false,导致路由守卫判定未登录。
解决方案
方案1:使用Pinia持久化插件(推荐)
通过插件自动同步状态到本地存储,实现持久化:
- 安装插件
npm install pinia-plugin-persistedstate # 或 yarn yarn add pinia-plugin-persistedstate
- 在Pinia初始化时注册插件
// main.js/main.ts import { createApp } from 'vue' import { createPinia } from 'pinia' import piniaPluginPersistedstate from 'pinia-plugin-persistedstate' import App from './App.vue' import router from './router' const pinia = createPinia() pinia.use(piniaPluginPersistedstate) const app = createApp(App) app.use(pinia) app.use(router) app.mount('#app')
- 修改auth store开启持久化
// auth.js import { defineStore } from "pinia"; const useLogin = defineStore("login", { state: () => ({ isLogged: false, }), actions: { setLoginValue() { this.isLogged = true; }, }, // 开启持久化,默认存储到localStorage persist: true, }); export { useLogin };
方案2:手动同步localStorage(无需插件)
手动在状态初始化和action中操作localStorage:
// auth.js import { defineStore } from "pinia"; const useLogin = defineStore("login", { state: () => ({ // 初始化时从localStorage读取状态,不存在则设为false isLogged: localStorage.getItem('login_isLogged') === 'true', }), actions: { setLoginValue() { this.isLogged = true; // 同步到localStorage localStorage.setItem('login_isLogged', 'true'); }, // 可选:添加登出方法,清除存储 setLogoutValue() { this.isLogged = false; localStorage.removeItem('login_isLogged'); } }, }); export { useLogin };
内容的提问来源于stack exchange,提问作者Bovver Boy
相关产品推荐
相关产品推荐

