news 2026/9/3 5:37:55

12.18 中后台项目-权限管理

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
12.18 中后台项目-权限管理

![[1280X1280 (46).PNG]]

![[1280X1280 (48).PNG]]

![[1280X1280 (50).PNG]]

权限管理总结

![[download_image.jpeg]]

模拟路由信息数据

adminRouter.json

[ { "path": "/dashboard", "component": "/layout/index.vue", "title": "Dashboard", "home": "/dashboard/console", "redirect": "/dashboard/console", "icon": "Edit", "name": "dashboard", "children": [ { "path": "console", "component": "/dashboard/console.vue", "title": "主控台", "icon": "Location" }, { "path": "monitor", "component": "/dashboard/monitor.vue", "title": "监控页", "icon": "Location" }, { "path": "workplace", "component": "/dashboard/workplace.vue", "title": "工作台", "icon": "Location" } ] }, { "path": "/student", "component": "/layout/index.vue", "title": "学生管理", "home": "/student/stuAdmin", "icon": "Edit", "name": "student", "children": [ { "path": "stuAdmin", "component": "/student/index.vue", "title": "学生管理", "icon": "Location", "name":"stuAdmin" }, { "path": "addStu", "component": "/student/addStu.vue", "title": "添加学生", "icon": "Location", "name":"addStu" }, { "path": "classAdmin", "component": "/student/classAdmin.vue", "title": "班级管理", "icon": "Location", "name":"classAdmin" } ] }, { "path": "/upload", "component": "/layout/index.vue", "title": "图片上传", "icon": "Edit", "name": "upload", "children": [ { "path": "index", "component": "/upload/index.vue", "title": "图片上传", "icon": "Location", "name":"uploadimg" } ] } ]

teacherRoutes.json

[ { "path": "/dashboard", "component": "/layout/index.vue", "title": "Dashboard", "home": "/dashboard/console", "redirect": "/dashboard/console", "icon": "Edit", "name": "dashboard", "children": [ { "path": "console", "component": "/dashboard/console.vue", "title": "主控台", "icon": "Location" }, { "path": "monitor", "component": "/dashboard/monitor.vue", "title": "监控页", "icon": "Location" }, { "path": "workplace", "component": "/dashboard/workplace.vue", "title": "工作台", "icon": "Location" } ] }, { "path": "/student", "component": "/layout/index.vue", "title": "学生管理", "home": "/student/stuAdmin", "icon": "Edit", "name": "student", "children": [ { "path": "stuAdmin", "component": "/student/index.vue", "title": "学生管理", "icon": "Location", "name":"stuAdmin" }, { "path": "addStu", "component": "/student/addStu.vue", "title": "添加学生", "icon": "Location", "name":"addStu" }, { "path": "classAdmin", "component": "/student/classAdmin.vue", "title": "班级管理", "icon": "Location", "name":"classAdmin" } ] } ]

从后端接口返回不同权限的路由数据 - user.js

let adminRoutes = require("../util/adminRoutes.json"); let teacherRoutes = require("../util/teacherRoutes.json"); let routes = { admin:adminRoutes, teacher:teacherRoutes } router.post('/login',async (req, res)=>{ // 1. 接收用户名和密码 let {account,pw} = req.body; // 2. 连接数据库,查看用户名 和 密码是否存在 let sql = `select * from user where account = '${account}' and pw = '${pw}'`; let data =await query(sql); let token = await setToken(account); let sendMsg = {}; if(data.data.length > 0){ let role = data.data[0].role; sendMsg = { msg:"登录成功", status:200, token, routesData:routes[role] } }else{ sendMsg = { msg:"用户名或者密码错误", status:102 } } console.log(sendMsg); res.send(sendMsg); });

前端接受路由信息

并渲染数据【接收一个路由信息】,在login页面接受数据 - index.vue

<script setup> import { ref, reactive } from "vue"; import { useRouter } from 'vue-router'; import { _login } from "@/api/request" // vite工具 // 针对解析的数据,进行组件懒加载 const Modules = import.meta.glob("@/pages/**/*.vue"); // console.log(Modules); const router = useRouter(); let formData = reactive({ account: "", pw: "" }) let login = async () => { let { data } = await _login(formData); // 接收路由信息中的值(只接受第一组路由信息,用于测试) let { children, component, home, icon, name, path, redirect, title } = data.routesData[0]; // 一级路由渲染 router.addRoute({ name, path, // 注意:引入的路径中,pages后面没有 / component: Modules[`/src/pages${component}`], meta: { title, icon, home }, redirect }) console.log(children[0]); // 二级路由渲染 router.addRoute("dashboard", { path: children[0].path, component: Modules[`/src/pages${children[0].component}`], meta: { title: children[0].title, icon: children[0].icon } }) // 打印路由信息 console.log(router.getRoutes()); if (data.status == 200) { sessionStorage.setItem('token', data.token); console.log(data); router.push('/'); } } </script>

遍历二级路由,使dashboard下面的二级路由都可以使用

// 二级路由 children.forEach(item => { let { path, component, title, icon } = item; router.addRoute("dashboard", { path, component: Modules[`/src/pages${component}`], meta: { title, icon } }) })

生成动态侧边栏

思路:登陆成功之后,将路由数据存储到vuex中,方便侧边栏NavMenu.vue调用数据

  1. 创建vuex文件

src/store/index.js

import { createStore } from 'vuex' // 创建一个新的 store 实例 const store = createStore({ state () { return { routesData: [] } }, mutations:{ addRoutersData:(state,payload)=>{ state.routesData = payload } } }) export default store
  1. 在全局注册vuex
import store from "./store" .... app.use(store);
  1. 登陆成功之后,数据存储到vuex中
import {useStore} from "vuex" let store = useStore(); let login = async () => { let { data } = await _login(formData); // 存入store中 store.commit("addRoutersData", data.routesData); ..... ..... }
  1. 在NavMenu.vue侧边栏中调用数据
import { useStore } from "vuex"; import { computed } from "vue"; const store = useStore(); const props = defineProps({ collapse: Boolean }) // 获取数据 console.log("111", store.state.routesData); let routesData = computed(() => { return store.state.routesData; }); // 渲染数据 <el-menu active-text-color="#ffd04b" background-color="#545c64" class="el-menu-vertical-demo" :default-active="$route.path" text-color="#fff" :default-openeds="['/dashboard']" :router="true" :collapse="props.collapse"> <h5 class="title">后台管理系统</h5> <!--template 标签只用来渲染数据,并不会在页面中显示--> <template v-for="(item,index) in routesData" :key="index"> <el-menu-item :index="item.path" v-if="item.children.length == 1"> <el-icon> <component :is="item.icon"></component> </el-icon> <span>{{item.title}}</span> </el-menu-item> <el-sub-menu index="/dashboard" v-else> <template #title> <el-icon> <component :is="item.icon"></component> </el-icon> <span>{{item.title}}</span> </template> <el-menu-item :index="second.path" v-for="(second,i) in item.children" :key="i"> <el-icon> <component :is="second.icon"></component> </el-icon> {{second.title}} </el-menu-item> </el-sub-menu> </template> </el-menu>

封装动态生成路由部分

  1. 创建文件 src/utils/generatorRoutes.js
// import { useRouter } from 'vue-router'; // const router = useRouter(); // 等价于下面的引入 // 引入router import router from "@/router/index.js"; // vite工具 // 针对解析的数据,进行组件懒加载 const Modules = import.meta.glob("@/pages/**/*.vue"); export const generatorRoutes = (routesData)=>{ let { children, component, home, icon, name, path, redirect, title } = routesData[0]; // 一级路由 router.addRoute({ name, path, component: Modules[`/src/pages${component}`], meta: { title, icon, home }, redirect }) // console.log(children[0]); // 二级路由 children.forEach(item => { let { path, component, title, icon } = item; router.addRoute("dashboard", { path, component: Modules[`/src/pages${component}`], meta: { title, icon } }) }) }
  1. 登陆页面中进行引入
import { generatorRoutes } from '@/utils/generatorRoutes.js'; let login = async () => { let { data } = await _login(formData); // 存入store中 store.commit("addRoutersData", data.routesData); // console.log(router.getRoutes()); if (data.status == 200) { sessionStorage.setItem('token', data.token); // -----------动态生成路由 start----------- generatorRoutes(data.routesData); // -----------动态生成路由 end----------- // console.log(data); router.push('/'); } }
  1. 遍历所有的路由信息
// import { useRouter } from 'vue-router'; // const router = useRouter(); // 等价于下面的引入 // 引入router import router from "@/router/index.js"; // vite工具 // 针对解析的数据,进行组件懒加载 const Modules = import.meta.glob("@/pages/**/*.vue"); export const generatorRoutes = (routesData)=>{ // 循环遍历 routesData.forEach((bigItem)=>{ let { children, component, home, icon, name, path, redirect, title } = bigItem; // 一级路由 router.addRoute({ name, path, component: Modules[`/src/pages${component}`], meta: { title, icon, home }, redirect }) // 二级路由 children.forEach(item => { let { path, component, title, icon } = item; router.addRoute(bigItem.name, { path, component: Modules[`/src/pages${component}`], meta: { title, icon } }) }) }) }

刷新页面内容消失的解决方案

方案:刷新的时候,判断是否存在token,如果存在,重新从vuex中读取路由数据

router/index.js

//路由拦截 router.beforeEach((to,from)=>{ let token = localStorage.getItem('token'); // 如果token不存在,并且要跳转的不是login页,则重定向到login if(!token && to.fullPath !== '/login'){ return { path:'/login' } } // 解决问题的代码 if(token){ // token存在有两种情况 // 一种是没刷新时,此时动态路由已经创建,可以正常使用 // 一种是刷新后,此时动态路由已经销毁,不能进行路由跳转,需要重新加载 let routesData = store.state.routesData; if (routesData.length === 0) { console.log('刷新'); routesData = JSON.parse(localStorage.getItem("routesData")); // 使用commit调用mutations下面的方法 store.commit("addRoutersData",routesData); generatorRoutes(routesData); // 重定向将要进入的路由 // 如果不加下面的代码,会在路由没有准备好就跳转,出现404 // 如果加,相当于延迟跳转,此时路由已经准备好 return { path:to.fullPath }; } } }) export default router

注意:当从本地存储中获取到路由数据之后,一定把把数据给vuex保存一份,否则即便有了数据,还是会一直进行 if routesData.length === 0 这一层判断 store.commit(‘addRoutersData’, routesData);

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/3 1:14:26

2026网安新蓝海:从合规到增长,洞悉产业发展的八大核心趋势与商机

2026年中国网络安全产业八大趋势 在近期发布的数说安全《2025年中国网络安全市场年度报告》中&#xff0c;总结出了2025年中国网络安全产业八大趋势&#xff0c;这是连续第四年总结发布网络安全产业最新动向与趋势方向&#xff0c;力求持续促进产业发展。 2025年中国网络安全…

作者头像 李华
网站建设 2026/9/2 5:13:53

动态内存管理(malloc、calloc、realloc)

1.内存布局内存布局的简单描述就是栈区、堆区、静态区1&#xff09;栈区&#xff1a;是来放置局部变量和函数形参等临时变量的。2&#xff09;堆区&#xff1a;是用来动态内存开辟的&#xff0c;malloc、calloc、free、realloc等函数都是在堆区上进行操作的。3&#xff09;静态…

作者头像 李华
网站建设 2026/9/2 22:05:57

linux文件同步机制(sync、fsync、fdatasync、O_SYNC)

sync&#xff1a;系统级文件同步&#xff0c;不等待数据写入完成&#xff0c;可能造成数据丢失&#xff0c;异步处理&#xff0c;由系统守护进程定时同步 fsync&#xff1a;特定文件&#xff08;fd&#xff09;的数据和元数据写入磁盘&#xff0c;后处理&#xff0c;开销较大 …

作者头像 李华
网站建设 2026/9/3 0:37:13

从红绿灯到让行规则,自动驾驶Agent如何精准决策?

第一章&#xff1a;自动驾驶Agent的交通规则 在自动驾驶系统中&#xff0c;Agent&#xff08;智能体&#xff09;必须遵循一套严谨的交通规则以确保道路安全与行为可预测性。这些规则不仅涵盖国家或地区的交通法规&#xff0c;还需结合实时环境感知与决策逻辑&#xff0c;使车辆…

作者头像 李华
网站建设 2026/9/3 4:22:07

Abaqus随机喷丸仿真全解析

abaqus 随机喷丸仿真&#xff0c;附带随机喷丸模型生成源程序&#xff0c;模型尺寸&#xff0c;丸粒尺寸&#xff0c;个数&#xff0c;角度&#xff0c;速度等均可自由改动源程序讲解视频&#xff0c;模型操作&#xff0c;后处理操作&#xff0c;模型文件均有喷丸微观仿真子程序…

作者头像 李华
网站建设 2026/9/2 23:47:33

Jimp图像处理服务器架构优化实战:从性能瓶颈到高效运行

当我们面对海量图片处理需求时&#xff0c;Jimp作为纯JavaScript图像处理库常常成为系统性能的瓶颈点。本文将从架构视角出发&#xff0c;通过三个关键层面的优化策略&#xff0c;帮助你构建高性能的Jimp图像处理服务&#xff0c;让服务器从容应对千万级图片处理请求。 【免费下…

作者头像 李华