6.2 KiB
路由
路由配置项
路由配置项不光参与路由的生成,也参与侧边栏、搜索结果的生成。
Route Attributes:
| 参数 | 说明 | 类型 | 默认 |
|---|---|---|---|
| hidden | 是否在侧边栏中显示 | boolean |
- |
| alwaysShow | 是否总是把只有一个子级的菜单以嵌套模式在侧边栏中展示 | boolean |
- |
| sort | 侧边栏的排序值,值越小越靠前 | number |
10000 |
Route.meta Attributes:
| 参数 | 说明 | 类型 | 默认 |
|---|---|---|---|
| title | 路由在侧边栏、面包屑、页签、搜索结果中的显示名称 | string |
- |
| icon | 图标名,支持svg-icon、el-icon | string |
- |
| affix | 是否在多页签中固定显示 | boolean |
- |
| noCache | true时缓存页面 | boolean |
- |
| activeMenu | 侧边栏当前激活菜单的index | string |
- |
| noAuth | true时路由不需要鉴权 | boolean |
router/constant下为true |
| iframe | 需要打开的iframe的地址 | string |
- |
| isDetailPage | 是否是详情页 | boolean |
- |
::: tip 注意 路由meta上的affix、noAuth、noCache会被子路由继承,优先使用子路由的值 :::
页面缓存
先总结一下路由页面被缓存的条件:
- 启用了多页签
(route.name || route.meta.isDetailPage) && route.meta.noCache && !route.meta.iframe
通常情况路由想做缓存都是通过 <keep-alive>,但是如果是像 /edit/1、/edit/2 这样的共用路由页面的详情页的话,
<keep-alive> 就满足不了需求,因为它是通过组件的 name 来区分组件的。
所以项目中仿照 <keep-alive> 写了 <keep-router-view-alive>,可以根据当前路由的路径来区分组件。
除此之外还有个问题,在共用了同一个组件的路由之间跳转的话,组件会被复用,假如有以下路由:
const component={template:`<input v-model="data">`, data: ()=> ({data:1})}
const routes = [
{ path: '/foo', component },
{ path: '/bar', component }
]
先访问 /foo,然后将输入框的值改为100,再访问 /bar ,会发现输入框的值还是100。
所以在 router.beforeEach 中做了判断,如果跳转前后的路由的 meta.isDetailPage 均为 true 的话,那么借助 /redirect 跳转一次,从而避免组件复用的问题
::: warning 注意
如果不使用meta.isDetailPage的话,需要缓存的页面的 name 必须和路由的 name 一致
:::
路由白名单
在 @/router/index.js 中有这么一句:
const whiteList = transformWhiteList(['/login', '/register', '/404', '/403'])
这个 whiteList 就是白名单,里面的值会被转为正则表达式,详细请查看path-to-regexp文档。
被whiteList 匹配的路由不需要验证,直接放行。
首屏加载效果
想体验的可以把 network 设为 slow 3g 就可以在在线实例看到效果。
原理很简单,在 index.html 里有这么一段:
<div id="app">
<div id="loader-wrapper">
<img>
<p>资源加载中......</p>
</div>
</div>
在 vuejs 初始化完成后,app 里的内容会被替换,从而实现加载效果。
骨架屏
通常情况下,路由组件都是以 import(...) 的形式异步引入,
如果想让路由在加载异步组件时显示,可以使用以下方式:
function lazyLoadView(component) {
const AsyncHandler = () => ({component, loading: Skeleton})
return Promise.resolve({
functional: true,
render(h, {data, children}) {
return h(AsyncHandler, data, children)
}
})
}
//将路由配置中的component项改为以下形式
component: () => lazyLoadView(import(...))
关于 AsyncHandler 的更多选项,可以查看官方文档
过渡动画
正常 <router-view> 使用过渡动画的方法应该是这样的:
<transition>
<keep-alive>
<router-view>
</keep-alive>
</transition>
但是由于项目中使用了自定义的 <keep-router-view-alive>,所以就变成这样的:
<keep-router-view-alive :include="cachedViews">
<transition :name="transitionName" mode="out-in">
<router-view>
</transition>
</keep-router-view-alive>
具体原因是 <transition> 中的代码硬编码了 <keep-alive>,导致如果按照往常写法的话,过渡动画不会生效。
项目中是根据页签的前后位置来决定路由动画的,比如从前面的页签跳转到后面的,那么动画是从左滑出,反之是从右滑出。
::: warning 注意
只有在启用了多页签的时候才会有上面的效果,否则默认是 el-fade-in-linear 动画。
:::
iframe
只需要按如下配置即可打开一个iframe:
{
"path":"/baidu",
"meta":{
"iframe":"https://www.baidu.com"
}
}
当向上面的路由跳转时,会隐藏路由页面,展示 <iframe> 标签,反之则隐藏。
另外,相同地址的iframe不会重复打开,想要刷新需使用 /redirect 跳转。
外链
也可以在路由中配置一个外链,只要在 path 中填写了合法的 url 路径,当你点击该路由菜单时就会新开这个页面。
例如:
{
"path": "https://www.baidu.com",
"meta": {
"title": "百度"
}
}