开发后台管理系统必备的需求:动态菜单权限管理、或者说路由权限动态管理
原理是通过addRoute
实现路由权限控制,一般分为两种:
- 后端生成当前用户相应的路由后由前端(用 Vue Router 提供的API)addRoutes 动态加载路由
- 前端写好所有的路由,后端返回当前用户的角色,然后根据事先约定好的每个角色拥有哪些路由对角色的路由进行分配
这里就不具体论述了
这里介绍一个个人研究的,在vite+vue3
下的动态菜单权限管理实现方案:
这是一个由后端动态菜单控制的解决方案,需要后端传异步组件的路径值
基于异步组件
和动态组件
,而不是addRoute
1.使用vue3和vite语法
defineAsyncComponent
是vue3定义异步组件的api
import.meta.glob
是vite的批量导入语法
<script>
import { defineAsyncComponent } from "vue"
let modules = import.meta.glob("../dynamicComponent/**/*.vue")
2.管理系统左侧一般是树菜单,右侧是对应菜单内容
第一步肯定是请求后端获取左侧树菜单,点击单个树菜单右侧显示对应菜单内容
在上一步我们已经通过vite批量导入获取dynamicComponent
文件夹下所有vue文件信息,在computed里面拼接动态组件路径即可
methods: {
/** 获取树菜单数据 */
async loadTreeData() {
const { data: res } = await http.post("xxx")
if (res.code === 0) {
this.treedata = res.data
}
},
/** 点击单个树菜单 */
handleNodeClick(data) {
this.currentNode = data
},
computed: {
/** 动态组件 */
dynamicComponent() {
// 这里是点击树节点后树节点上的数据,vueUrl字段是跟后端沟通后返回的前端项目vue文件路径
let filename = this.currentNode.vueUrl
return defineAsyncComponent(modules[`../dynamicComponent/${filename}.vue`])
},
},
3.动态组件
<div class="container">
<div class="tree">
...
</div>
<div class="tree-right">
<transition name="fade-transform" mode="out-in">
<component
v-if="dynamicComponent"
:is="dynamicComponent"
></component>
</transition>
</div>
</div>
可以看到核心代码思路其实是非常简单的,开发右侧内容区域的vue页面只需要放在dynamicComponent
文件夹下,跟后端沟通好文件路径传值即可
比如后端传值user/common
,对应前端项目vue文件路径是dynamicComponent/user/common.vue
安全性思考
dynamicComponent
方案是具备安全性的,因为异步组件和动态组件只能通过后端传值的方式进行vue页面渲染,用户是不能通过路由进行页面访问的
假设网站攻击者可以伪造后端返回结果,那这种情况下当然可以访问到dynamicComponent
的页面,但同理,这种也可以访问到addRoute
的页面,所以这点上两者安全性是一样的,并且项目开发中一般还会有token请求头
,页面数据请求会进行校验,所以综上dynamicComponent
解决方案比较addRoute
方案并没有安全性问题