在做项目中,一般我们都会遇到这样的需求,头部的导航后台是可以动态修改的(添加,删除),并且可以无限级的添加子导航例如下图
要实现这个其实是听容易,就是做个递归头部,(具体参考上一节,vue递归组件)
不过一般我们需要实现上述导航的时候,需要的数据结构是这样的
var routes = [
{
path: '/A-1',
name: 'A1',
component: (resolve) => require(['@/views/A.vue'],resolve),
meta: {
text: 'A-一级菜单',
query: {
a: '查询字符串-一级菜单'
}
},
children: [
{
path: '/A2',
name: 'A2',
component: (resolve) => require(['@/views/A-2.vue'],resolve),
meta: {
text: 'A-二级菜单-1',
query: {
a: '查询字符串-二级菜单'
}
},
children: [
{
path: '/A-3',
name: 'A3',
component: (resolve) => require(['@/views/A-3.vue'],resolve),
meta: {
text: 'A-三级菜单',
query: {
a: '查询字符串-三级菜单'
}
},
children: []
}
]
}
]
},
{
path: '/B-1',
name: 'B1',
component: (resolve) => require(['@/views/B.vue'],resolve),
meta: {
text: 'B-一级菜单',
query: {
a: 'B-查询字符串-一级菜单'
}
},
children: [
{
path: '/B2',
name: 'B2',
component: (resolve) => require(['@/views/B-2.vue'],resolve),
meta: {
text: 'B-二级菜单',
query: {
a: 'B-查询字符串-二级菜单'
}
},
children: [
{
path: '/B-3',
name: 'B3',
component: (resolve) => require(['@/views/B-3.vue'],resolve),
meta: {
text: 'B-三级菜单',
query: {
a: 'B-查询字符串-三级菜单'
}
},
children: []
}
]
}
]
},
{
path: '/B-1',
name: 'B1',
component: (resolve) => require(['@/views/B.vue'],resolve),
meta: {
text: 'B-一级菜单',
query: {
a: 'B-查询字符串-一级菜单'
}
},
children: [
{
path: '/B2',
name: 'B2',
component: (resolve) => require(['@/views/B-2.vue'],resolve),
meta: {
text: 'B-二级菜单',
query: {
a: 'B-查询字符串-二级菜单'
}
},
children: [
{
path: '/B-3',
name: 'B3',
component: (resolve) => require(['@/views/B-3.vue'],resolve),
meta: {
text: 'B-三级菜单',
query: {
a: 'B-查询字符串-三级菜单'
}
},
children: []
}
]
}
]
}
];
就是一级套一级的数据,大家都是很熟悉的了,这样看上去我们的路由结构好像是没什么问题,因为基于这样的结构,我们的头部导航都OK了,但是如果我们之间把这样的结构用 this.$router.addRoutes(routes)加入到路由进去后,你会发现点二级菜单,三级菜单的时候,路由渲染不出来了,因为子路由的组件,只能渲染在父路由的组件中(不知道这么描述是不是很好),而且还必须加<router-view></router-view>,但是我们的需求是不管点击哪个,都把组件应该渲染在首页,所以其实这样的结构就不靠谱的,把以上的结构变成兄弟节点就好了,所以我们需要封装个函数
//分解路由,把父子路由变成兄弟路由,额不知道怎么去描述这个函数了,大概就这意思吧,这个函数其实是不完美的,因为meta是对象,我们这里引用了对象(应该做深拷贝),所以会有问题的,不过我们并不做修改,所以拿来用还是没毛病的
function breakRoutes (arr) {
var newArr = [];
pushRoutes (arr);
function pushRoutes (arr) {
for (var i=0;i<arr.length;i++) {
newArr.push({
path: arr[i].path,
name: arr[i].path,
component: arr[i].component,
meta: arr[i].meta,
});
if (arr[i].children && arr[i].children[0]) {
pushRoutes (arr[i].children)
}
}
}
return newArr
}
在添加路由之前先breakRoutes (routes),然后再this.$router.addRoutes(routes)加入到路由进去,这样做才没有问题的