news 2026/4/14 18:52:05

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/4/9 7:05:02

2025届计算机专业大学生,敢问路在何方?

目录 互联网裁员 计算机专业本科生就业情况 计算机专业转角遇到爱 网络安全行业特点 如何入门学习网络安全 零基础入门 互联网裁员 这两天&#xff0c;关于大厂&#xff0c;特别是互联网大厂裁员、优化员工的新闻再次受到关注。 从裁员情况看&#xff0c;谷歌、亚马逊…

作者头像 李华
网站建设 2026/4/12 2:03:20

计算机科学与技术,软件工程,网络空间安全这三个专业考研怎么选?

前言 三个专业本质上都是万金油专业。三个专业间本身都可以横跳找工作。只是人事部可能会关心招人要求里会有点要求&#xff0c;这也是写个人学历或工作简历问题。除了专项课题研发外&#xff0c;几乎没有什么差别。 只能根据你的未来工作打算来规划 1&#xff09;考研后继续…

作者头像 李华
网站建设 2026/4/12 1:43:10

SmokeAPI终极指南:完全解锁Steam游戏DLC的免费方案

SmokeAPI终极指南&#xff1a;完全解锁Steam游戏DLC的免费方案 【免费下载链接】SmokeAPI Legit DLC Unlocker for Steamworks 项目地址: https://gitcode.com/gh_mirrors/smo/SmokeAPI 还在为Steam游戏的高价DLC发愁吗&#xff1f;想要体验完整游戏内容却不想掏空钱包&…

作者头像 李华
网站建设 2026/4/8 17:36:41

2026年如何成功入行网络安全?这份精准学习与择业指南请收好

在2026年&#xff0c;随着科技的飞速发展&#xff0c;人类社会已经全面迈入了数字化时代。万物互联、人工智能、大数据、云计算等前沿技术正以前所未有的速度改变着我们的生活和工作方式。然而&#xff0c;正如硬币的两面&#xff0c;这一数字化的浪潮也带来了前所未有的网络安…

作者头像 李华
网站建设 2026/4/11 19:07:48

2026网安入行指南:如何抓住行业东风,成为企业争抢的新兴赛道人才?

2026年网络安全行业的前景看起来非常乐观。根据当前的趋势和发展&#xff0c;一些趋势和发展可能对2025年网络安全行业产生影响&#xff1a; 5G技术的广泛应用&#xff1a;5G技术的普及将会使互联网的速度更快&#xff0c;同时也将带来更多的网络威胁和安全挑战。网络安全专家…

作者头像 李华
网站建设 2026/4/8 23:10:58

一根线,六台伺服:耐达讯自动化的PROFIBUS六路集线器“省钱魔法”

在电子制造车间&#xff0c;产线改造和设备增添是常态。你是否也遇到过这样的窘境&#xff1a;PLC上唯一的PROFIBUS-DP端口早已占满&#xff0c;但为了提升产线柔性&#xff0c;必须在贴片机后段增加多个伺服单元&#xff0c;用于精密点胶、视觉定位或组装。传统方案无非两条路…

作者头像 李华