项目地址github
https://github.com/cc147151/v3-admin
定义路由:(含有children的路由对象将视为菜单栏的sub-menu)
(根路由添加name,是因为router.removeRoute()方法参数只支持name删除,在退出登录的动作)
1.定义一个路由时,通常把它当作一个含有多个子菜单来创建,因为我们需要指定layout组件
2.hidden属性为true时候,代表左边菜单栏需要隐藏它。
3.如果为一级菜单,children数组只需拥有一项即可,(需要多项时候,其它子项添加hidden属性,否则就不视为一级菜单)
4.处理代码在sotre/modules/permission.js
约定: 定义带有hidden(不需要菜单显示的)的路由,其同级必须至少有一个是菜单
定义路由如下:
一级路由 (针对菜单栏的一级菜单,要给予children,忘记添加children内容,会隐藏它,但是一定要有一个children数组)
// 可参考router/visit.js
import layout from '@/layout/index'
export const visit = [
{
path: '/visit',
component: layout,
redirect: '/visit/index',
// 必填,router.removeRoute()方法参数只支持name删除
name: 'Visit',
children: [
{
path: '/visit/index',
component: () => import('@/views/visit/index.vue'),
meta: {
title: '浏览量'
}
},
{
path: '/visit/detail',
component: () => import('@/views/visit/detail/index.vue'),
// hidden代表不显示在左边菜单栏
hidden: true,
meta: {
title: '详情'
}
}
]
}
]
5.多级路由时候,一定要添加title(例:营销中心),用于菜单(el-sub-menu)显示文字
多级路由
import layout from '@/layout/index'
const RouteView = {
render() {
return (
<>
<RouterView></RouterView>
</>
)
}
}
export const marking = [
{
path: '/marking',
component: layout,
redirect: '/marking/active',
name: 'Marking',
meta: {
title: '营销中心'
},
children: [
{
path: '/marking/active',
meta: {
title: '活动管理'
},
component: () => import('@/views/marking/index')
},
{
hidden: true,
path: '/marking/manageDetail',
meta: {
title: '活动管理详情'
},
component: () => import('@/views/marking/manageDetail')
},
{
path: '/marking/theme',
component: RouteView,
redirect: '/marking/theme/yuanDan',
meta: {
title: '活动主题'
},
children: [
{
path: '/marking/theme/yuanDan',
component: () => import('@/views/marking/theme/yuanDan/index.vue'),
meta: {
title: '元旦活动'
}
},
{
path: '/marking/theme/newYear',
component: () => import('@/views/marking/theme/newYear/index.vue'),
meta: {
title: '春节活动'
}
},
{
path: '/marking/theme/detail',
component: () => import('@/views/marking/theme/detail/index'),
meta: {
title: '活动详情'
},
hidden: true
}
]
}
]
}
]
核心代码:
// 从定义的私有路由表里筛选出后端返回的指定路由表
// menus:后端返回的菜单路由表 privateRoutes定义的私有所有路由表
const privateRoutesArr = filterPrivateRoutes(menus, privateRoutes)
privateRoutesArr.push({
path: '/:pathMatch(.*)*',
name: '404',
component: () => import('@/views/error-page/404'),
hidden: true
})
// 处理一下一级菜单问题(只有一个子路由的时候该子路由就作为一级菜单显示)
const menuRoutersArr = getMenuRoutersArr([
...publicRoutes,
...privateRoutesArr
])
function filterPrivateRoutes(menus, privateRoutes) {
return menus.map((itemMenu) => {
const routeInfo = {}
const obj = privateRoutes.find(
(itemRoute) => itemRoute.path === itemMenu.path
)
Object.assign(routeInfo, obj)
if (itemMenu.menuName && routeInfo.meta) {
routeInfo.meta.title = itemMenu.menuName
}
if (itemMenu.icon && routeInfo.meta) {
routeInfo.meta.icon = itemMenu.icon
}
if (itemMenu.children) {
routeInfo.children = filterPrivateRoutes(itemMenu.children, obj.children)
}
// 就算itemMenu没有children,也要用find找到与之对应得本地路由(可能包含非菜单页面or 一级路由)
return routeInfo
})
}
function getMenuRoutersArr(allMenu) {
return allMenu.map((item) => {
if (item.children) {
const levelArr = item.children.filter((item) => !item.hidden)
if (levelArr.length === 1) {
item = levelArr[0]
}
}
return item
})
}