当前位置: 首页 > news >正文

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);

http://www.cnnetsun.cn/news/136516.html

相关文章:

  • QtScrcpy高刷投屏优化指南:告别卡顿,享受流畅体验
  • 终极移动端Windows应用运行指南:从零到流畅体验
  • 大学里的网络安全专业为什么没多少人就读?
  • 信息安全和网络空间安全这2个专业怎么选?老网安告诉你答案!
  • 英语发音MP3音频库:119,376个单词标准发音完整解决方案
  • 瞄准2026:AI安全、数据隐私与云原生——网络安全趋势预测与挑战分析
  • 重磅收藏!Java程序员转AI大模型:从代码高手到AI架构师的进阶指南
  • 2026网络安全进阶路线:盘点撬动高薪的四大关键证书
  • LangGraph实战教程:构建智能旅游规划助手,深入理解AI工作流架构【值得收藏】
  • 淘宝直播弹幕采集完整指南:5分钟快速上手数据分析
  • 文本驱动可视化:5分钟掌握专业级图表制作
  • Clipper2多边形处理技术深度解析与实战应用
  • 错过再等十年:AI驱动的生物制药Agent智能实验设计新范式
  • 造纸车间的“信号指挥官”:耐达讯自动化Profinet六路集线器,让变频器“步调一致”
  • MaterialDesignInXamlToolkit实战指南:5步打造现代化WPF界面
  • 中东电商市场,正在成为中国卖家的必争之地!
  • 为什么你的边缘Agent总是部署失败?深度剖析常见陷阱与对策
  • 一文搞定前端CSS常用布局
  • Kotaemon用户行为分析插件开发教程
  • 额温枪PCBA方案开发全流程规划
  • Kotaemon针灸穴位查询:图文结合精准定位
  • 二极管钳位三电平VSG仿真模型 1.加入中点电位平衡 2.仿真有视频教程 3.THD均<5%
  • 通达信轻松买卖点副图,源码分享
  • 仅限内部分享:电力巡检Agent路径生成模型参数调优全记录
  • ChromePass密码找回工具:轻松获取Chrome保存的所有密码
  • BookmarkHub:告别浏览器书签混乱的智能同步神器
  • 51、保障系统安全:从漏洞扫描到灾难恢复的全面指南
  • DearPyGUI:为什么这款Python GUI框架正在重新定义界面开发?
  • Matlab模拟OAM螺旋谱展开,包括光束本征态、各类湍流、衍射、干涉下的OAM谱分布
  • 【核工业Agent故障处理全攻略】:揭秘高危场景下的7大应急响应策略