Vue 3 js Router 无法访问 Pinia 中用户存储的状态(需要 Hydrate pinia 状态)

问题描述 投票:0回答:1

我正在尝试检查 Vue 3 js 应用程序中的路由授权。这个想法是应该根据用户的角色(NavGuard)来定义授权。因此,当用户登录(JWT 令牌)时,我将他的角色添加到 Pinia 商店(useUserStore)的状态中。

我已经阅读了有关“在组件之外使用商店”的文档,并且当用户登录并被重定向到主页时它实际上正在工作。如果我 console.log(store) 我可以看到用户的角色。

但是,每当我导航到另一个页面时,console.logged 的状态就是初始状态(所有值均为 null)。我猜问题是在该状态准备好之前加载了路由器。

import NotFoundView from '@/views/public/NotFoundView.vue' import { useUserStore } from '@/stores/user' import pinia from "@/stores/store.js"; const router = createRouter({ history: createWebHistory(import.meta.env.BASE_URL), routes: [ { path: '/', name: 'home', component: HomeView }, { path: '/about', name: 'about', component: AboutView }, { path: '/:pathMatch(.*)*', name: 'NotFound', component: NotFoundView }, ] }) router.beforeEach(async (to, from) => { const store = await useUserStore(); console.log(store.user) }) export default router

Main.js

import { createApp } from 'vue' import store from '@/stores/store' import App from '@/App.vue' import router from '@/router' import axios from 'axios' axios.defaults.baseURL = 'http://127.0.0.1:8000' const app = createApp(App) app.use(store) app.use(router, axios) router.isReady().then(() => { app.mount("#app"); });

store.js

import { createPinia } from "pinia"; const pinia = createPinia(); export default pinia;

用户.js

import { defineStore } from 'pinia' import axios from 'axios' export const useUserStore = defineStore('user', { id: 'user', state: () => ({ user: { isAuthenticated: false, id: null, name: null, email: null, access: null, refresh: null, role: null, } }), actions: { initStore() { console.log('initStore') if (localStorage.getItem('user.access')) { this.user.access = localStorage.getItem('user.access') this.user.refresh = localStorage.getItem('user.refresh') this.user.id = localStorage.getItem('user.id') this.user.name = localStorage.getItem('user.name') this.user.email = localStorage.getItem('user.email') this.user.isAuthenticated = true this.refreshToken() console.log('Initialized user:', this.user) } }, })

此代码正在工作,因为当用户登录时我具有正确的预期行为。但是我需要在每个页面之前检查用户角色,而不仅仅是在登录时检查。

有什么建议吗?

感谢您抽出时间阅读!

javascript vue.js store pinia
1个回答
0
投票

这是代码的修改版本,可以帮助您实现所需的行为:

更新您的路由器配置:
  1. import { createRouter, createWebHistory } from 'vue-router'; import { useUserStore } from '@/stores/user'; const router = createRouter({ history: createWebHistory(import.meta.env.BASE_URL), routes: [ { path: '/', name: 'home', component: HomeView }, { path: '/about', name: 'about', component: AboutView }, { path: '/:pathMatch(.*)*', name: 'NotFound', component: NotFoundView }, ] }); router.beforeEach(async (to, from, next) => { const store = useUserStore(); await store.initStore(); // Make sure the user state is initialized. // Now, you can access the user's role and perform authorization checks. const userRole = store.user.role; // You can implement your authorization logic here. // For example, check if the userRole has access to the route. // You can also handle cases like redirecting to a login page if not authenticated. // For simplicity, let's assume all users can access all routes. // Replace this with your actual authorization logic. if (userRole !== null) { next(); // Allow navigation. } else { // Redirect to a login page or show an unauthorized message. // Modify this according to your application's requirements. next('/login'); // Redirect to a login page if the user's role is not defined. } }); export default router;
更新您的 user.js 存储:
在您的 user.js 存储中,似乎您有一个 initStore 操作来初始化用户状态。您可以在应用程序启动时调用此操作,以确保在任何路线导航之前初始化用户状态。

// user.js import { defineStore } from 'pinia'; import axios from 'axios'; export const useUserStore = defineStore('user', { // ... (your existing state and actions) actions: { initStore() { if (localStorage.getItem('user.access')) { // ... (your existing code to initialize the user state) } } } });

通过执行这些步骤,您的 Vue 3 应用程序现在应该在每个页面导航之前正确检查用户的角色,甚至在登录后也是如此。请记住将 router.beforeEach 防护中的占位符逻辑替换为基于用户角色的实际授权检查。

© www.soinside.com 2019 - 2024. All rights reserved.