vue動(dòng)態(tài)面包屑路由組件實(shí)現(xiàn),無(wú)污染、易配置
這幾天開(kāi)發(fā)一個(gè)vue項(xiàng)目,因?yàn)轫?yè)面非常多,而且有面包屑需求
開(kāi)始想法:<適用于有面包屑的頁(yè)面少的情況> 每個(gè)頁(yè)面用vue路由傳參實(shí)現(xiàn),每次跳轉(zhuǎn)傳參,頁(yè)面根據(jù)參數(shù)設(shè)置面包屑路由;
后來(lái)想法:規(guī)劃好路由,將路由和面包屑一一對(duì)應(yīng)起來(lái),頁(yè)面加載后解析路由,組合成面包屑即可(如下圖),路由的名稱(chēng)是對(duì)應(yīng)起來(lái)添加到配置中
下面是我的兩種思路和組件實(shí)現(xiàn)(至于面包屑的樣式實(shí)現(xiàn)并不難,這里直接用elemetUI組件的,我主要是說(shuō)動(dòng)態(tài)面包屑思路,并不是面包屑樣式,如果UI組件不同,只需要自己做一些簡(jiǎn)單修改即可):
實(shí)現(xiàn):
breadBox1.0.vue:
<!--
v1.0
breadBox 路由配置好,面包屑直接對(duì)應(yīng)
-->
<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 {
//手動(dòng)配置項(xiàng):breadListIm為路由與面包屑名稱(chēng)對(duì)應(yīng)關(guān)系,breadLoadName為面包屑組件路由
breadLoadName: '/breadBox',
breadListIm: [
{
path: '01',
name: '一級(jí)'
},
{
path: '02',
name: '二級(jí)'
},
{
path: '03',
name: '三級(jí)'
},
],
breadListLast: []
};
},
methods: {
loadChange() {
this.breadListLast = []
if (this.$route.path.indexOf(this.breadLoadName) === -1) {
console.log('面包屑路由地址breadLoadName沒(méi)有配置正確!')
} 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 = ''
//刪除掉數(shù)組的前1個(gè),提升遍歷性能
breadList.splice(0, 1)
//考慮到順序問(wèn)題,只能先遍歷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);
}
},
//頁(yè)面掛載之后,解析路由,給出面包屑,路由里面一定要含有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>
優(yōu)點(diǎn):插拔輕松,容易配置(樣式現(xiàn)在基于elementUI,完全可以改成任意面包屑組件)
直接將breadBox放在 router/index.js 的路由中間即可,當(dāng)然,上一層組件模塊要加上 <router-view></router-view>


最后:上面的思路親測(cè)可行,配合vue-router的path和redirect用的不錯(cuò),但考慮到可能會(huì)出現(xiàn)重復(fù)路由配置過(guò)多,又寫(xiě)了一版兼容開(kāi)始的想法,
當(dāng)然這次吸取教訓(xùn),將配置路由也提了出來(lái)。
更適合于路由沒(méi)有規(guī)劃的項(xiàng)目,拿來(lái)即用。
breadBox2.0.vue:
<!--
breadBox v2.0 說(shuō)明:1.0和2.0選擇一種方法配置動(dòng)態(tài)路由即可
1.0 breadBox 面包屑跟隨路由變化,此方法需要面包屑與路由顯示順序一致,例如path:01/02/03 面包屑也是01/02/03,
2.0 增加路由參數(shù)配置項(xiàng),動(dòng)態(tài)面包屑,面包屑跟隨參數(shù)變化
(2.0方法雖然萬(wàn)能,但在頁(yè)面過(guò)多的時(shí)候不推薦,每次路由跳轉(zhuǎn)帶上面包屑參數(shù)會(huì)造成麻煩
2.0推薦使用情況:在路由和面包屑根本對(duì)不上,重定向也不好用的時(shí)候,或者重復(fù)路由配置過(guò)多的,或者僅一兩個(gè)頁(yè)面有面包屑又想引入此組件的)
優(yōu)點(diǎn):插拔輕松,容易配置(樣式基于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手動(dòng)配置項(xiàng):breadListIm為路由與面包屑名稱(chēng)對(duì)應(yīng)關(guān)系,breadLoadName為面包屑組件路由
//v2.0手動(dòng)配置項(xiàng):breadListParam為路由與面包屑名稱(chēng)對(duì)應(yīng)關(guān)系,breadBoxIdName為路由參數(shù)名
breadLoadName: '/breadBox',
breadListIm: [
{
path: '01',
name: '一級(jí)'
},
{
path: '02',
name: '二級(jí)'
},
{
path: '03',
name: '三級(jí)'
},
],
breadListParam:{
"1":[{path:"/home/01",name:"一級(jí)01"},
{path:"/home/02/01",name:"二級(jí)01"},
{path:"/home/03/02/01",name:"三級(jí)01"}],
"2":[{path:"/home/01",name:"一級(jí)02"},
{path:"/home/02/01",name:"二級(jí)02"},
{path:"/home/03/02/01",name:"三級(jí)02"}]
},
breadBoxIdName:'breadBoxId',
breadListLast: [],
};
},
methods: {
loadChange() {
this.breadListLast = []
//獲取參數(shù)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沒(méi)有配置正確!')
} 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 = ''
//刪除掉數(shù)組的前1個(gè),提升遍歷性能
breadList.splice(0, 1)
//考慮到順序問(wèn)題,只能先遍歷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);
}
},
//頁(yè)面掛載之后,解析路由,給出面包屑,路由里面一定要含有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>
