在最近的项目中,思考如何把面包屑导航和侧边栏与页面路径绑定到一起。中间走过很多弯路,现在已经找到了比较好的解决方案。
环境
- element-ui;
- Vue;
- Vue Router;
想法 1.0
使用index路由跳转。
根据对侧边栏的点击,使用方法(select
和open
)去全局缓存当前激活的菜单(default-active
)和展开的数组(default-openeds
)的数据,并保存到localStorage
通过参考我的一篇文章:
一些Vue缓存处理
对数据进行缓存和进入页面获取。
发现element-ui
中 SubMenu
的index也会进行隐式的数据更新(虽然不会造成路由跳转但是面包屑的数据是根据indexPath展示的,会出现多拼接 SubMenu
的index情况),造成体验上的不友好,于是废弃。
想法 2.0
根据当前的页面路由路径去获取数据,对当前的面包屑和侧边栏进行配置。
注意区分$router
和$route
这两个对象。
$router
是方法
$route
是属性
在侧边栏组件中对Menu Attribute
添加
:default-active="this.$route.path"
还好,element-ui
会默认的把选择的菜单组展开,省去了对菜单展开的配置。
在面包屑中
<template>
<el-breadcrumb separator-class="el-icon-arrow-right">
<el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
<el-breadcrumb-item v-for="item in routerArr" :key="item.id">{{CN[item]}}</el-breadcrumb-item>
</el-breadcrumb>
</template>
<script>
export default {
computed: {
routerArr() {
return this.$route.path.substr(1).split("/");
}
}
}
</script>
要实现这个效果你必须对递归组件的index进行严格配置。
格式大概是这样的:
{
self: { index: "/index", icon: "el-icon-odometer", title: "首页" },
child: []
},
{
self: {
index: "authority",
icon: "el-icon-s-tools",
title: "权限管理"
},
child: [
{
self: {
index: "/authority/shop",
icon: "",
title: "公司管理"
},
child: []
},
{
self: {
index: "/authority/shopgroup",
icon: "",
title: "部门管理"
},
child: []
},
{
self: {
index: "/authority/user",
icon: "",
title: "用户管理"
},
child: []
},
{
self: {
index: "/authority/role",
icon: "",
title: "角色管理"
},
child: []
}
]
},
有时候我们需要设置的层级,没必要使用嵌套路由,可以使用别名来进行配置。
path: "/",
component: () => import("@/views/Main"),
children: [
{
path: "index",
name: "index",
component: () => import("@/views/Index"),
meta: {}
},
{
path: "shop",
name: "shop",
alias: "/authority/shop",
component: () => import("@/views/Authority/Shop")
},
{
path: "shopgroup",
name: "shopgroup",
alias: "/authority/shopgroup",
component: () => import("@/views/Authority/ShopGroup")
},
{
path: "role",
name: "role",
alias: "/authority/role",
component: () => import("@/views/Authority/Role")
},
{
path: "user",
name: "user",
alias: "/authority/user",
component: () => import("@/views/Authority/User")
},
]
}
这样可以根据路径进行导航和侧边栏联动了。
有一个坏处就是到达一个页面会有两个路径,不过这也不是什么大问题。