可信网站证书,wordpress download 插件,泛站群,银川网站建设一条龙服务#x1f680; Pinia Vue Router 权限控制#xff08;终极完整版#xff09; 一、整体设计理念
功能说明认证模式Token Role Permission动态路由后端返回#xff0c;前端动态挂载超管放行超级管理员跳过所有权限校验按钮权限v-permission 指令动态标题根据路由 meta.tit… Pinia Vue Router 权限控制终极完整版 一、整体设计理念
功能说明认证模式Token Role Permission动态路由后端返回前端动态挂载超管放行超级管理员跳过所有权限校验按钮权限v-permission 指令动态标题根据路由 meta.title 自动动态设置缓存优化Pinia 持久化动态路由注入缓存 二、核心模块拆分
src/store/user.tspermission.tsrouter/index.tsroutes.tsutils/permission.tsdirective/permission.tsapi/user.tsviews/Layout.vueLogin.vueDashboard.vueAdmin.vueEditor.vueNotFound.vue三、完整代码实战
1️⃣ user.ts — 用户 Store
import { defineStore } from pinia;export const useUserStore defineStore(user, {state: () ({token: ,roles: [] as string[],permissions: [] as string[],isSuperAdmin: false // 超级管理员标识}),actions: {login(token: string, roles: string[], permissions: string[]) {this.token token;this.roles roles;this.permissions permissions;this.isSuperAdmin roles.includes(super-admin);},logout() {this.token ;this.roles [];this.permissions [];this.isSuperAdmin false;}},persist: true
});2️⃣ api/user.ts — 模拟后台接口
import type { RouteRecordRaw } from vue-router;export function getAsyncRoutes(): PromiseRouteRecordRaw[] {return new Promise(resolve {setTimeout(() {resolve([{path: /admin,component: () import(/views/Admin.vue),meta: { title: 后台管理, roles: [admin], permission: admin:manage }},{path: /editor,component: () import(/views/Editor.vue),meta: { title: 编辑页面, roles: [editor], permission: editor:edit }}]);}, 300);});
}3️⃣ permission.ts — 权限 Store
import { defineStore } from pinia;
import { constantRoutes } from /router/routes;
import type { RouteRecordRaw } from vue-router;
import { getAsyncRoutes } from /api/user;
import { useUserStore } from ./user;export const usePermissionStore defineStore(permission, {state: () ({routes: [] as RouteRecordRaw[]}),actions: {async generateRoutes() {const userStore useUserStore();const asyncRoutes await getAsyncRoutes();const accessedRoutes asyncRoutes.filter(route {if (userStore.isSuperAdmin) return true;if (route.meta?.roles !userStore.roles.some(role route.meta?.roles?.includes(role))) {return false;}return true;});this.routes constantRoutes.concat(accessedRoutes);return accessedRoutes;}}
});4️⃣ utils/permission.ts — 按钮权限工具
import { useUserStore } from /store/user;export function hasPermission(permission: string): boolean {const userStore useUserStore();return userStore.isSuperAdmin || userStore.permissions.includes(permission);
}5️⃣ directive/permission.ts — v-permission 指令
import { Directive } from vue;
import { hasPermission } from /utils/permission;const permission: Directive {mounted(el, binding) {const value binding.value;if (value !hasPermission(value)) {el.parentNode?.removeChild(el);}}
};export default permission;全局注册 import permission from /directive/permission;
app.directive(permission, permission);使用示例
el-button v-permissionadmin:manage仅管理员按钮/el-button6️⃣ routes.ts — 基础路由
import type { RouteRecordRaw } from vue-router;export const constantRoutes: RouteRecordRaw[] [{ path: /login, component: () import(/views/Login.vue), meta: { title: 登录 } },{path: /,redirect: /dashboard,component: () import(/views/Layout.vue),children: [{ path: dashboard, component: () import(/views/Dashboard.vue), meta: { title: 首页 } }]},{ path: /:pathMatch(.*)*, component: () import(/views/NotFound.vue), meta: { title: 404 } }
];7️⃣ router/index.ts — 动态路由守卫 动态 Title
import { createRouter, createWebHistory } from vue-router;
import { constantRoutes } from ./routes;
import { useUserStore } from /store/user;
import { usePermissionStore } from /store/permission;const router createRouter({history: createWebHistory(),routes: constantRoutes
});const whiteList [/login];router.beforeEach(async (to, from, next) {const userStore useUserStore();const permissionStore usePermissionStore();if (to.meta?.title) {document.title to.meta.title as string;}if (userStore.token) {if (permissionStore.routes.length 0) {const routes await permissionStore.generateRoutes();routes.forEach(route router.addRoute(route));next({ ...to, replace: true });} else {next();}} else {if (whiteList.includes(to.path)) {next();} else {next(/login);}}
});export default router;四、核心升级逻辑总结
模块升级点超级管理员登录时 isSuperAdmin 直接放行所有路由和按钮动态 Title每次切换路由动态修改 document.title双重模型路由走 roles 控制按钮走 permissions 控制 五、完整权限框架架构图
- 登录成功返回- token- roles角色列表- permissions按钮权限码- asyncRoutes动态路由列表- 前端- Pinia缓存用户信息- 动态注入路由- 路由守卫控制进入- v-permission 控制按钮显示✅ 目前框架特点 企业项目标准权限架构 完整前后端配合 灵活易扩展 稳定性高