vue動態(tài)面包屑路由組件實(shí)現(xiàn)洼专,無污染、易配置
這幾天開發(fā)一個(gè)vue項(xiàng)目孵构,因?yàn)轫撁娣浅6嗥ㄉ蹋矣忻姘夹枨?/p>
開始想法:<適用于有面包屑的頁面少的情況> 每個(gè)頁面用vue路由傳參實(shí)現(xiàn),每次跳轉(zhuǎn)傳參颈墅,頁面根據(jù)參數(shù)設(shè)置面包屑路由蜡镶;
后來想法:規(guī)劃好路由,將路由和面包屑一一對應(yīng)起來恤筛,頁面加載后解析路由官还,組合成面包屑即可(如下圖),路由的名稱是對應(yīng)起來添加到配置中
下面是我的兩種思路和組件實(shí)現(xiàn)(至于面包屑的樣式實(shí)現(xiàn)并不難毒坛,這里直接用elemetUI組件的望伦,我主要是說動態(tài)面包屑思路,并不是面包屑樣式,如果UI組件不同粘驰,只需要自己做一些簡單修改即可):
實(shí)現(xiàn):
breadBox1.0.vue:
<!--
v1.0
breadBox 路由配置好屡谐,面包屑直接對應(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 {
//手動配置項(xiàng):breadListIm為路由與面包屑名稱對應(yīng)關(guān)系,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 = ''
//刪除掉數(shù)組的前1個(gè)度秘,提升遍歷性能
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>
優(yōu)點(diǎn):插拔輕松唆貌,容易配置(樣式現(xiàn)在基于elementUI,完全可以改成任意面包屑組件)
直接將breadBox放在 router/index.js 的路由中間即可,當(dāng)然氮兵,上一層組件模塊要加上 <router-view></router-view>
image.png
v1.0效果
最后:上面的思路親測可行挤忙,配合vue-router的path和redirect用的不錯(cuò),但考慮到可能會出現(xiàn)重復(fù)路由配置過多酪刀,又寫了一版兼容開始的想法粹舵,
當(dāng)然這次吸取教訓(xùn),將配置路由也提了出來骂倘。
更適合于路由沒有規(guī)劃的項(xiàng)目眼滤,拿來即用。
breadBox2.0.vue:
<!--
breadBox v2.0 說明:1.0和2.0選擇一種方法配置動態(tài)路由即可
1.0 breadBox 面包屑跟隨路由變化,此方法需要面包屑與路由顯示順序一致历涝,例如path:01/02/03 面包屑也是01/02/03,
2.0 增加路由參數(shù)配置項(xiàng)诅需,動態(tài)面包屑,面包屑跟隨參數(shù)變化
(2.0方法雖然萬能荧库,但在頁面過多的時(shí)候不推薦堰塌,每次路由跳轉(zhuǎn)帶上面包屑參數(shù)會造成麻煩
2.0推薦使用情況:在路由和面包屑根本對不上,重定向也不好用的時(shí)候分衫,或者重復(fù)路由配置過多的场刑,或者僅一兩個(gè)頁面有面包屑又想引入此組件的)
優(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手動配置項(xiàng):breadListIm為路由與面包屑名稱對應(yīng)關(guān)系,breadLoadName為面包屑組件路由
//v2.0手動配置項(xiàng):breadListParam為路由與面包屑名稱對應(yīng)關(guān)系,breadBoxIdName為路由參數(shù)名
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 = []
//獲取參數(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沒有配置正確摇邦!')
} 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)
//考慮到順序問題屎勘,只能先遍歷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>
V2.0效果