面包屑简介
面包屑(Breadcrumb)是网页中一个常见的模块,用于显示用户在网站中当前的所处的位置,并且可以向上导航。常见的前端组件库都会包含这个组件,例如:
- Element UI Breadcrumb 面包屑
- Ant Design Vue Breadcrumb 面包屑
面包屑的代码:
<el-breadcrumb separator="/"><el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item><el-breadcrumb-item :to="{ path: '/' }">活动管理</el-breadcrumb-item><el-breadcrumb-item :to="{ path: '/' }">活动列表</el-breadcrumb-item><el-breadcrumb-item :to="{ path: '/' }">活动详情</el-breadcrumb-item>
</el-breadcrumb>
这种一项一项手写面包屑的方法带来了很多重复性工作,比如每个页面中都需要写一遍“首页”的面包屑,所有“活动管理”下的所有页面,也都需要写一遍“活动管理”。这时如果路由需要调整,那么所有页面的面包屑都要进行修改,非常繁琐。因此如果可以自动生成面包屑,就能够减轻很多重复性工作,也方便代码维护。
方法1 嵌套路由
我们首先想到使用嵌套路由解决这个问题。嵌套路由本身就是带有层级的,天然适合自动生嵌套路由。Vue Router中对嵌套路由有文档说明。
方法描述
- 按照Vue Router规范设置多级路由表,meta标签中放置面包屑名称。
- 面包屑实现代码中使用route.matched获取多级路由,直接显示即可。
优点和缺点
优点
- 实现最简单,最方便。
- 能够适应多种情形,无论是刷新页面还是直接访问子页面URL,都能保证面包屑的一致性。
- 能够保存路由参数,query和定义在路由中的params都可以保存下来,上级跳转功能的体验较好。
缺点
- 要求存在可以手写的路由表,使用自动生成路由的工程难以使用。例如vite-plugin-pages插件使用文件目录自动生成路由表,虽然可以自动生成嵌套路由,但是不方便设置meta。
- 要求路由必须是清晰的树形结构,必须使用多级路由表。如果不路由结构不方便设置为树形,或者是网状结构,则不能使用此方法。
嵌套路由的这个方法基本是自动生成路由的首选方法,可以较好的实现功能。但是我使用了vite-plugin-pages插件,因此还是要寻求其他方法。
vue如何获取上级路由
在Vue.js中,获取上级路由可以通过访问this.$route
对象并利用其matched
属性来实现。具体来说,以下是获取上级路由的步骤:
1、通过this.$route.matched
属性获取当前匹配的路由数组;
2、获取上级路由的路径或名称。使用this.$route
对象可以方便地访问当前路由信息。下面详细介绍这些步骤。
一个数组,包含当前路由的所有嵌套路径片段的路由记录,一个路由匹配到的所有路由记录会暴露为 $route 对象 (还有在导航守卫中的路由对象) 的 $route.matched 数组
一、使用 this.$route.matched 获取当前路由数组
this.$route.matched
是一个数组,包含当前匹配的路由记录。每个记录都是一个路由对象,按照从根路径到当前路径的顺序排列。通过这种方式可以轻松获取上级路由的信息。
const matchedRoutes = this.$route.matched;
例如,对于路径 /parent/child
,matchedRoutes
数组可能包含两个对象:
[{ path: '/parent', ... },{ path: '/child', ... }
]
二、获取上级路由信息
const parentRoute = matchedRoutes.length > 1 ? matchedRoutes[matchedRoutes.length - 2] : null;
这个parentRoute
对象包含了上级路由的所有信息,如路径、名称、组件等。
面包屑
面包屑其实就是标题,类似于小型的导航,当前到了页面的哪个位置。
也即是到了哪一层, 在header部分横向做一个展示,展示一个层次的关系。层级也是看路由的层级,将路由里面的层级横向去放了而已。
外层工作台是可以直接写死的,里面这些是活的, 工作负载,deploy这些就是活的。之前写侧边栏取到的是router path,现在取router matched。
deployment是侧边的栏的item,那么工作负载是侧边栏的sub-item。应该是路由规则的父属性,另外一个是路由规则的子属性。
所以无论是children为1还是children为0,都是需要其name的。
router给我们提供了一个方法,router能够拿到当前的父级的路由信息,会返回父亲的信息和子信息,这样就可以做层级关系了。
<el-header class="header"><el-row :gutter="20"><el-col :span="1"><!--折叠按钮 根据isCollapse来设置是否可以展开和折叠--><div class="header-collapse" @click="onCollapse"><el-icon><component :is="isCollapse ? 'expand':'fold'"/> </el-icon></div> </el-col><el-col :span="10"> <!--面包屑--><div class="header-breadcrumb"><el-breadcrumb separator="/"><!--这个有点像超链接,跳转到哪里key尽量不要去使用index,那个前提是idx会发生变化,但是在这里基本上不会发生变化,因为在这里是一个路由,不会太对路由发生变化--><el-breadcrumb-item :to="{ path: '/' }">工作台</el-breadcrumb-item><!--for循环取出经过的路由信息--><template v-for="(matched,idx) in this.$route.matched" ;key="idx"><!--做个优雅的判断,如果matched.name存在的情况下才拿出来,不存在就有bug了--><el-breadcrumb-item v-if="matched.name">{{ matched.name }}</el-breadcrumb-item></template></el-breadcrumb></div></el-col></el-row></el-header>/*面包屑样式优化*/.header-breadcrumb {padding-top: 0.8em;}