所使用的Vue3+Ts+vite 手动搭建的项目,对于vue-cli搭建的项目同样适用。项目流程不多赘述,直接上用法
一、动态添加路由
{
key: 唯一值id,
title: 名称,
icon: 图标,
children: [{
parentKey: 父id,
key: 唯一值id,
title:名称,
name:路由名称
path: 文件路径,
type: 类型, MENU菜单 BUTTON 具体按钮
hiddle:作为菜单是否隐藏 true false
}]
}
1、取出非第一级的所有数据
/**
*
* @param data 动态菜单
* @returns
*/
const getRouterTreeAdd = (data: any = []) => {
let router: any = []
const childrens = data.map((item: any) => item.children) || []
childrens.map((item: any) => {
router = [...router, ...item]
})
return router.filter((item: any) => item.path)
}
2、映射出所有路由规则
/**
*
* @param menuTree 登录后获取的菜单
* @returns
*/
const getRouterRules = (menuTree: any) => {
const routerTree = getRouterTreeAdd(Object.assign([], menuTree))
// 获取菜单权限与映射数据 匹配对应信息 生成动态路由
const getMatching = (data: any = []) => {
data.map((item: any) => {
item.name = item.name
item.path = `/${item.name}` //与名称同名方便后期管理
item.meta = {title: item.title}
item.component = () => import(element.path)
const children: any = item.children || []
if (children.length) {
getMatching(children)
}
})
}
// 调用事件生成规则
getMatching(routerTree)
return routerTree
}
3、添加路由
// 记得引入router
import Router from '../router/index'
// 添加路由规则
add_route(state: any) {
const rules = getRouterRules(Object.assign([],state.menuTree) )
let {routes}: any = Router.options
if (rules.length === 0) return;
routes[2].children = rules
Router.addRoute(routes[2])
},
注:vue3中使用addRoute、vue2.x应该使用addRoutes,具体查看官方网站
4、 登录成功后 保存菜单数据,保存后在vuex直接触发添加事件即可 this.commit('add_route')
使用时别忘了在vuex->mutations、vuex->actions 添加相应的触发事件
二、动态路由刷新后消失解决办法
网上解决办法有不少,但是看起来很复杂。在此有一个新思路解决。
思路:路由消失了是不是再次添加就可以了?
问题:刷新后消失什么时候添加?在哪里添加?
//定义变量判断是否已经动态添加过,如果刷新后load永远为 0
let load = 0
//导航守卫
router.beforeEach((to, from, next) => {
// 获取菜单
const menuTree = store.getters.getMenuTree
//非登录、有菜单数据、 没有进行添加(或者刷新了)
if (load === 0 && menuTree.length && to.name!=='Login') {
load++
//再次调用存储菜单数据(前提是在存储的地方有调用添加路由规则)、或者直接调用动态添加路由规则事件
store.dispatch("SAVE_MENUTREE", menuTree);
//添加后跳转到应访问的地址
next({path: to.fullPath})
}
})