vue动态面包屑路由组件实现,无污染、易配置
这几天开发一个vue项目,因为页面非常多,而且有面包屑需求
开始想法:<适用于有面包屑的页面少的情况> 每个页面用vue路由传参实现,每次跳转传参,页面根据参数设置面包屑路由;
后来想法:规划好路由,将路由和面包屑一一对应起来,页面加载后解析路由,组合成面包屑即可(如下图),路由的名称是对应起来添加到配置中
下面是我的两种思路和组件实现(至于面包屑的样式实现并不难,这里直接用elemetUI组件的,我主要是说动态面包屑思路,并不是面包屑样式,如果UI组件不同,只需要自己做一些简单修改即可):
实现:
breadBox1.0.vue:
<!--
v1.0
breadBox 路由配置好,面包屑直接对应
-->
<template>
<div class="breadEval">
<div class="breadTitle">
<el-breadcrumb separator="/">
<el-breadcrumb-item>您的位置:</el-breadcrumb-item>
<el-breadcrumb-item :to="item.path" v-for="item of breadListLast" :key="item.path">
{{item.name}}
</el-breadcrumb-item>
</el-breadcrumb>
</div>
<router-view></router-view>
</div>
</template>
<script>
export default {
//面包屑解决方案,此方法只适用于面包屑与路由显示顺序一致,例如path:01/02/03 面包屑也是01/02/03
data() {
return {
//手动配置项:breadListIm为路由与面包屑名称对应关系,breadLoadName为面包屑组件路由
breadLoadName: '/breadBox',
breadListIm: [
{
path: '01',
name: '一级'
},
{
path: '02',
name: '二级'
},
{
path: '03',
name: '三级'
},
],
breadListLast: []
};
},
methods: {
loadChange() {
this.breadListLast = []
if (this.$route.path.indexOf(this.breadLoadName) === -1) {
console.log('面包屑路由地址breadLoadName没有配置正确!')
} else {
let breadListAgo = this.$route.path.split(this.breadLoadName)
// let breadListAgo = '/index/indexSchool/breadList/01/02/03'.split(this.breadLoadName)
let breadList = breadListAgo[1].split('/')
let obje = {}
let breadIndex = ''
//删除掉数组的前1个,提升遍历性能
breadList.splice(0, 1)
//考虑到顺序问题,只能先遍历breadList,再遍历breadListIm
for (let p of breadList) {
for (let q of this.breadListIm) {
if (p === q.path) {
breadIndex += '/' + q.path
obje.path = breadListAgo[0] + this.breadLoadName + breadIndex
obje.name = q.name
this.breadListLast.push(obje)
obje = {}
}
}
}
// 打印路由配置
// console.log(JSON.stringify(this.breadListLast))
}
}
},
watch: {
$route(to, from) {
this.loadChange()
// console.log(to.path);
}
},
//页面挂载之后,解析路由,给出面包屑,路由里面一定要含有breadCom组件的path
mounted: function () {
this.loadChange()
}
};
</script>
<style lang="scss" scoped>
.breadEval {
position: relative;
font-size: 14px;
height: 100%;
background: #F3F7FD;
.breadTitle{
padding: 20px 30px;
background: #fff;
}
}
</style>
优点:插拔轻松,容易配置(样式现在基于elementUI,完全可以改成任意面包屑组件)
直接将breadBox放在 router/index.js 的路由中间即可,当然,上一层组件模块要加上 <router-view></router-view>
最后:上面的思路亲测可行,配合vue-router的path和redirect用的不错,但考虑到可能会出现重复路由配置过多,又写了一版兼容开始的想法,
当然这次吸取教训,将配置路由也提了出来。
更适合于路由没有规划的项目,拿来即用。
breadBox2.0.vue:
<!--
breadBox v2.0 说明:1.0和2.0选择一种方法配置动态路由即可
1.0 breadBox 面包屑跟随路由变化,此方法需要面包屑与路由显示顺序一致,例如path:01/02/03 面包屑也是01/02/03,
2.0 增加路由参数配置项,动态面包屑,面包屑跟随参数变化
(2.0方法虽然万能,但在页面过多的时候不推荐,每次路由跳转带上面包屑参数会造成麻烦
2.0推荐使用情况:在路由和面包屑根本对不上,重定向也不好用的时候,或者重复路由配置过多的,或者仅一两个页面有面包屑又想引入此组件的)
优点:插拔轻松,容易配置(样式基于elementUI)
-->
<template>
<div class="breadEval">
<div class="breadTitle">
<el-breadcrumb separator="/">
<el-breadcrumb-item>您的位置:</el-breadcrumb-item>
<el-breadcrumb-item :to="item.path" v-for="item of breadListLast" :key="item.path">
{{item.name}}
</el-breadcrumb-item>
</el-breadcrumb>
</div>
<router-view></router-view>
</div>
</template>
<script>
export default {
//面包屑解决方案,
data() {
return {
//v1.0手动配置项:breadListIm为路由与面包屑名称对应关系,breadLoadName为面包屑组件路由
//v2.0手动配置项:breadListParam为路由与面包屑名称对应关系,breadBoxIdName为路由参数名
breadLoadName: '/breadBox',
breadListIm: [
{
path: '01',
name: '一级'
},
{
path: '02',
name: '二级'
},
{
path: '03',
name: '三级'
},
],
breadListParam:{
"1":[{path:"/home/01",name:"一级01"},
{path:"/home/02/01",name:"二级01"},
{path:"/home/03/02/01",name:"三级01"}],
"2":[{path:"/home/01",name:"一级02"},
{path:"/home/02/01",name:"二级02"},
{path:"/home/03/02/01",name:"三级02"}]
},
breadBoxIdName:'breadBoxId',
breadListLast: [],
};
},
methods: {
loadChange() {
this.breadListLast = []
//获取参数breadBoxId值
let breadBoxId = this.$route.query[this.breadBoxIdName]
console.log(breadBoxId)
if( undefined == breadBoxId || breadBoxId == null || '' == breadBoxId ){
if (this.$route.path.indexOf(this.breadLoadName) === -1) {
console.log('面包屑路由地址breadLoadName没有配置正确!')
} else {
let breadListAgo = this.$route.path.split(this.breadLoadName)
// let breadListAgo = '/index/indexSchool/breadList/01/02/03'.split(this.breadLoadName)
let breadList = breadListAgo[1].split('/')
let obje = {}
let breadIndex = ''
//删除掉数组的前1个,提升遍历性能
breadList.splice(0, 1)
//考虑到顺序问题,只能先遍历breadList,再遍历breadListIm
for (let p of breadList) {
for (let q of this.breadListIm) {
if (p === q.path) {
breadIndex += '/' + q.path
obje.path = breadListAgo[0] + this.breadLoadName + breadIndex
obje.name = q.name
this.breadListLast.push(obje)
obje = {}
}
}
}
};
}else{
this.breadListLast = this.breadListParam[breadBoxId]
}
// 打印路由配置
console.log(JSON.stringify(this.breadListLast))
}
},
watch: {
$route(to, from) {
this.loadChange()
// console.log(to.path);
}
},
//页面挂载之后,解析路由,给出面包屑,路由里面一定要含有breadCom组件的path
mounted: function () {
this.loadChange()
}
};
</script>
<style lang="scss" scoped>
.breadEval {
position: relative;
font-size: 14px;
height: 100%;
background: #F3F7FD;
.breadTitle{
padding: 20px 30px;
background: #fff;
}
}
</style>