基于vue-router的matched实现面包屑功能
本文主要介绍了基于vue-router的matched实现面包屑功能,分享给大家,具体如下:
如上图所示,就是常见的面包屑效果,面包屑的内容一般来说,具有一定的层级关系,就以上图为例,首先是进入首页,然后点击左侧导航,进入活动管理下的活动列表页面,然后点击某一条数据,进入活动详情页面
这正好与vue-router的mached属性所获取的结果有着相似的原理,所以可以基于此来实现面包屑效果!
这里我使用了elementui的面包屑组件和导航菜单组件,先贴出最后的效果图:
路由配置
项目结构:
侧边导航栏是首页、电子数码、服装鞋帽页面都会显示的,所以我创建了一个layout组件,将这三个路由的component都指向该组件,并将导航栏和面包屑都写在layout组件中
因为该功能的实现依赖于路由的层级嵌套关系,所以要提前构思好路由的配置,我这里的路由配置如下:
const routes = [
//匹配空路由,重定向到根路由
{
path:'',
redirect: '/home',
meta:{
showInbreadcrumb:false
}
},
//根路由
{
path:'/home',
component: ()=>import('@/views/layout/index.vue'),
name:'home',
meta:{
title:"首页",
showInbreadcrumb:true
}
},
//电子数码
{
path:'/electronics',
name:'电子数码',
component: ()=>import('@/views/layout/index.vue'),
redirect: '/electronics/computer',
meta:{
title:"电子数码",
showInbreadcrumb:true
},
children:[
{
path:'computer',
name:'computer',
component()=>import('@/views/electronics/children/computer/index.vue'),
meta:{
title:"电脑",
showInbreadcrumb:true
}
},
{
path:'phone',
name:'手机',
component: ()=>import('@/views/electronics/children/phone/index.vue'),
meta:{
title:"手机",
showInbreadcrumb:true
}
},
{
path:'tv',
name:'电视',
component: ()=>import('@/views/electronics/children/tv/index.vue'),
meta:{
title:"电视",
showInbreadcrumb:true
}
}
]
},
//服装鞋帽
{
path:'/clothing',
name:'服装鞋帽',
component: ()=>import('@/views/layout/index.vue'),
redirect: '/clothing/tops',
meta:{
title:"服装鞋帽",
showInbreadcrumb:true
},
children:[
{
path:'tops',
name:'上装',
component: ()=>import('@/views/clothing/children/tops/index.vue'),
meta:{
title:"上装",
showInbreadcrumb:true
}
},
{
path:'lower',
name:'下装',
component: ()=>import('@/views/clothing/children/lower/index.vue'),
meta:{
title:"下装",
showInbreadcrumb:true
}
},
{
path:'shoes',
name:'鞋子',
component: ()=>import('@/views/clothing/children/shoes/index.vue'),
meta:{
title:"鞋子",
showInbreadcrumb:true
}
}
]
},
//放在最后,当前面所有路由都没匹配到时,会匹配该路由,并重定向到根路由
{
path:'*',
redirect:'/',
meta:{
showInbreadcrumb:false
}
},
]
这里我配置的路由有首页、电子数码、服装鞋帽,这三个是一级路由,其中电子数码和服装鞋帽还有二级路由,在meta中我自定义了数据,showInbreadcrumb用于判断是否显示在面包屑中,title为在面包屑显示的名称
获取路由信息
模板部分:
///class="lazy" data-src/views/layout/index.vue
<template>
<div class="layout">
<!-- 侧边导航栏 -->
<div class="sideMenu">
<el-menu
default-active="0"
class="el-menu-vertical-demo"
>
<div v-for="(item,index) in routes" :key="index" :index="index+''">
<!-- 没有二级菜单的 -->
<el-menu-item :index="index+''" v-if="!item.children">
<router-link :to="{name:item.name}">{{item.meta.title}}</router-link>
</el-menu-item>
<!-- 有二级菜单的 -->
<el-submenu :index="index+''" v-else>
<template slot="title">{{item.meta.title}}</template>
<el-menu-item v-for="(item_,index_) in item.children" :key="index_" :index="index+'-'+index_">
<router-link :to="{name:item_.name}">{{item_.meta.title}}</router-link>
</el-menu-item>
</el-submenu>
</div>
</el-menu>
</div>
<div class="content">
<!-- 面包屑 -->
<div class="breadcrumb">
<el-breadcrumb separator-class="el-icon-arrow-right">
<el-breadcrumb-item v-for="(item,index) in breadcrumb" :key="index" :to="{ path: item.path}">{{item.meta.title}}</el-breadcrumb-item>
</el-breadcrumb>
</div>
<!-- 路由出口 -->
<router-view></router-view>
</div>
</div>
</template>
js部分:
export default {
data(){
return{
}
},
computed:{
// 侧边导航数据
routes(){
// 从$router.options中获取所有路由信息并过滤
return this.$router.options.routes.filter((item)=>{
return item.meta.showInbreadcrumb
});
},
// 面包屑数据
breadcrumb(){
// 根据路由配置meta中的showInbreadcrumb字段过滤
let matchedArr = this.$route.matched.filter((item)=>{
return item.meta.showInbreadcrumb}
);
// 因为首页比较特殊,必须一直显示在面包屑第一个,如果没有首页路由信息,手动添加到最前面
if(matchedArr[0].meta.title !== '首页'){
matchedArr.unshift(
{
path:'/home',
meta:{
title:"首页",
showInbreadcrumb:true
}
},
)
}
return matchedArr;
},
}
}
注意:拿到this.$route.matched后,不能在其结果上直接追加然后再过滤,否则会页面错乱并且报错,应该先filter,这样会返回一个新的数组,然后再判断追加首页信息
最终效果
到此这篇关于基于vue-router的matched实现面包屑功能的文章就介绍到这了,更多相关vue-router matched面包屑内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341