# 路由和侧边栏
路由和侧边栏是组织起一个后台应用的关键骨架。
Vue 前端项目侧边栏和路由绑定在一起,只要在 src/router/index.js 配置对应的路由,侧边栏就能动态生成。大大减轻了手动重复编辑侧边栏的工作量。当然需要在配置路由的时候遵循一些约定的规则。
# 配置项
以下是 Vue 前端项目配置路由时提供的配置项。
// 当设置 true 的时候该路由不会在侧边栏出现,如 401,login 等页面,或者如一些编辑页面 /edit/1
hidden: true // (默认 false)
//当设置 noRedirect 的时候该路由在面包屑导航中不可被点击
redirect: 'noRedirect'
// 当一个路由的 children 声明的路由大于一个时,自动会变成嵌套的模式
// 只有一个时,会将那个子路由当作根路由显示在侧边栏
// 若想不管路由的 children 声明的个数都显示根路由,可以设置 alwaysShow: true,这样它会忽略之前定义的规则,一直显示根路由
alwaysShow: true
name: 'router-name' // 设定路由的名字,一定要填写,不然使用 <keep-alive> 时会出现各种问题
meta: {
roles: ['ROLE_ADMIN', 'ROLE_EDITOR'] // 设置该路由进入的权限,支持多个权限叠加
title: 'title' // 设置该路由在侧边栏和面包屑中展示的名字
icon: 'svg-name' // 设置该路由的图标,支持 svg-class,也支持 element-ui 的 el-icon-x
noCache: true // 如果设置为 true,则不会被 <keep-alive> 缓存(默认 false)
breadcrumb: false // 如果设置为 false,则不会在 breadcrumb 面包屑中显示(默认 true)
affix: true // 若设置为 true,会固定在 tags-view 中(默认 false)
// 当路由设置了该属性,则会高亮相对应的侧边栏。这在某些场景非常有用,例如一篇文章的列表页路由为:/article/list
// 点击文章进入文章详情页,这时候路由为 /article/1,若想在侧边栏高亮文章列表的路由,就可以进行以下设置
activeMenu: '/article/list'
}
示例:
{
path: '/permission',
component: Layout,
redirect: '/permission/index', // 重定向地址,在面包屑中点击会重定向到的地址
hidden: true, // 不在侧边栏
alwaysShow: true, // 一直显示根路由
meta: { roles: ['ROLE_ADMIN', 'ROLE_EDITOR'] }, // 可以在根路由设置权限,所有子路由都继承了这个权限
children: [{
path: 'index',
component: ()=>import('permission/index'),
name: 'permission',
meta: {
title: 'permission',
icon: 'lock', // 图标
roles: ['ROLE_ADMIN', 'ROLE_EDITOR'], // 也可以给每一个子路由设置自己的权限
noCache: true // 不会被 <keep-alive> 缓存
}
}]
}
# 路由
路由分为两种:constantRoutes 和 asyncRoutes。
constantRoutes: 代表那些不需要动态判断权限的路由,如登录页、404 等通用页面。
asyncRoutes: 代表那些需要动态判断权限并通过 addRoutes 动态添加的页面。
所有的路由页面都已使用路由懒加载。其他配置和 vue-router 官方没有区别。
404 页面一定要最后加载,否则后面的所有页面都会被拦截到 404。
# 侧边栏
侧边栏主要基于 element-ui 的 el-menu 改造。
侧边栏通过读取路由并结合权限判断而动态生成,而且还需要支持路由无限嵌套,所以还使用到了递归组件,代码在 src/layout/components/Sidebar。
改造了 element-ui 默认侧边栏不少的样式,所有的 css 都可以在 src/styles/sidebar.scss 找到,根据自己的需求进行修改。
# unique-opened
可以在 src/layout/components/Sidebar/index.vue 中设置 unique-opened 控制侧边栏是否只保持一个子菜单的展开。
# 多级目录(嵌套路由)
如果路由是多级目录,例如本项目 src/views/nested 有三级路由嵌套的情况下,不要忘记还要手动在二级目录的根文件下添加一个 <router-view>,有多少级路由嵌套就需要多少个 <router-view>。
<!-- 父级路由组件 -->
<template>
<div>
<!-- xxx html 内容 -->
<router-view />
</div>
</template>
# 点击侧边栏 刷新当前路由
在用 SPA(单页面应用) 开发模式之前,用户每次点击侧边栏都会重新请求这个页面,渐渐养成了点击侧边栏当前路由来刷新 view 的习惯。但现在 SPA 已不一样,用户点击当前高亮的路由并不会刷新 view,因为 vue-router 会拦截这个路由;它会判断 url 若没有任何变化,就不会触发任何钩子或者是 view 的变化。
我们可以通过不断改变 url 的 query 来触发 view 的变化。监听侧边栏每个 link 的 click 事件,每次点击都给 router push 一个不一样的 query 来确保重新刷新 view。
clickLink(path) {
this.$router.push({
path,
query: {
t: +new Date() //保证每次点击路由的 query 项都是不一样的,确保重新刷新 view
}
})
}
不要忘了在 router-view 加上一个特定唯一的 key,如 <router-view :key="$route.path"></router-view>
# 面包屑
Vue 前端项目也封装了一个面包屑导航,通过 watch $route 变化动态生成。它和 menu 一样,也可以通过之前那些配置项控制一些路由在面包屑中的展现。例如可以在路由中声明 breadcrumb:false 让其不在 breadcrumb 面包屑显示。
代码在 src/components/Breadcrumb。
# 侧边栏滚动
Vue 前端项目使用 el-scrollbar 处理侧边栏滚动,代码在 src/layout/components/Sidebar。
# 侧边栏外链
我们可以在侧边栏配置一个外链,只要在 path 中填写合法的 url 路径,当点击侧边栏的时候就会新开一个页面。例如:
{
"path": "external-link",
"component": Layout,
"children": [
{
"path": "https://www.baidu.com",
"meta": { "title": "externalLink", "icon": "link" }
}
]
}
# 侧边栏默认展开
若需要默认展开侧边栏的某些 sub-menu,可以通过 default-openeds 来进行设置,代码在 src/layout/components/Sidebar/index.vue。
<el-menu
:default-openeds="['/example','/nested']" // 添加本行代码
:default-active="activeMenu"
:collapse="isCollapse"
:background-color="variables.menuBg"
:text-color="variables.menuText"
:unique-opened="false"
:active-text-color="variables.menuActiveText"
:collapse-transition="false"
mode="vertical"
>
<sidebar-item v-for="route in permission_routes" :key="route.path" :item="route" :base-path="route.path" />
</el-menu>