时间:2021-04-23 09:27:51 | 栏目:vue | 点击:次
面包屑应该是我们在项目中经常使用的一个功能,一般情况下它用来表示我们当前所处的站点位置,也可以帮助我们能够更快的回到上个层级。
今天我们就来聊聊如何在 Vue 的项目中实现面包屑功能。以下案例都是使用 Element-UI 进行实现。
最笨的方式
首先我们想到的最笨的方法就是在每个需要面包屑的页面中固定写好。
<template> <div class="example-container"> <el-breadcrumb separator="/"> <el-breadcrumb-item v-for="(item,index) in breadList" :key="index" :to="{ path: item.path }" >{{item.name}}</el-breadcrumb-item> </el-breadcrumb> </div> </template> <script> export default { name: "Example", data() { return { breadList: [{ name: "首页", path: "/home" }, { name: "系统设置", path: "/setting" }, { name: "用户管理", path: "/setting/usermanage" }] }; } }; </script>
如果按照上述方式去实行的话,虽然我们可以完成面包屑的功能,但是它不够灵活,在每个需要的页面添加,带来的维护成本是巨大的。
最主要的是你们的产品天天变需要咋办,还不累死。有人说登哥我就喜欢这么改,只有这样我才会有工作量。
好吧那当我没说,但是我劝你善良,登哥劝你一句,把那些大量重复的工作尽可能的赶紧做完,剩下的时间你才能自由安排,进行充能呀。
否则,你拿什么进步?普通的人总是喜欢抱怨没有时间,而优秀的人就是这么把时间省下来的。他们知道什么事情重要,什么事情不重要。
不过还是有人会说我就想安安静静写写代码,其他的我不想。那也行,不过这样写显然不够逼格。
利用 路由元信息
上面的方法,非常的不够逼格,显然不是我们想要的,那我们再来看看第二种实现方式。
我们可以把路径结构配置在 Route meta 属性中。
const router = new Router({ routes: [{ path: '/example', name: 'example', component: Example, meta: { breadList: [{ name: "首页", path: "/home" }, { name: "系统设置", path: "/setting" }, { name: "用户管理", path: "/setting/usermanage" }] } } ] }); export default router;
然后我们直接在页面中使用计算属性获取数据。
<template> //...省略 </template> <script> export default { name: "Example", computed: { breadList() { return this.$route.meta.breadList || []; } } }; </script>
这样也能实现我要想的效果,但是这个还是显得比较冗余,路由数据已经定义好一次结构,还要加上一个专门的面包屑数据,造成代码的重复,还是不够逼格。
那接下来登哥教你一招比较有逼格的。准备好小本本记下来。
路由对象 matched 属性
首先我们先来看看官方对 matched 的介绍。
matched:返回一个数组,包含当前路由的所有嵌套路径片段的路由记录 。
可以看到当我们定义好路由结构以后,我们就可以获取到当前页面的路由记录。
首先我们先创建一个面包屑的组件。
//Breadcrumb.vue <script> export default { data() { return { breadList: [] // 路由集合 }; }, watch: { $route() { this.getBreadcrumb(); } }, methods: { isHome(route) { return route.name === "home"; }, getBreadcrumb() { let matched = this.$route.matched; //如果不是首页 if (!this.isHome(matched[0])) { matched = [{ path: "/home", meta: { title: "首页" } }].concat(matched); } this.breadList = matched; } }, created() { this.getBreadcrumb(); } }; </script>
创建完组件之后,在需要的地方注入即可。如果你的网页结构布局合理恰当的话只需要一处引用就可以所有网页使用啦。
真可谓 “一处代码供全局”。
定义的路由信息如下:
const router = new Router({ routes: [ { path: '/', redirect: '/home' }, { path: '/home', name: 'home', component: Home, meta: { title: '首页' } }, { path: '/setting', name: "setting", component: () => import('./views/setting/Setting.vue'), redirect: '/setting/user', meta: { title: '系统设置' }, children: [{ path: 'user', component: () => import('./views/setting/UserMange.vue'), name: 'usermanage', meta: { title: '用户管理' } }, { path: 'message', component: () => import('./views/setting/MesMange.vue'), name: 'mesmanage', meta: { title: '短信管理' } }] }, { path: '/example', name: 'example', component: Example, meta: { title: '综合实例' } } ] }); export default router;
可以看到我们非常灵活的实现出我们需要的效果。可能这个功能并没有完善,比如有些页面不需要怎么办?
其实只要我们过滤下数据就可以实现,比如利用 meta 不存在时面包屑数据置空,或者增加一个数据标示面包屑的现实隐藏。等等都是一种思路。小伙伴们不妨发挥自己的想象试试吧。
看十遍不如自己撸一遍。这样很快就能掌握知识点。最后上下效果图给大家观摩。
总结