之前在网上搜面包屑带参数跳转,一直没找到比较优雅的方案,于是决定自己写。
(网上的大多方案都是存在vuex中,那nm每个带参数的跳转的url都要单独处理,鬼tm想这样做)
思路
*前提 对vue-router的route结构有所了解 路由和侧边栏 | vue-element-admin (panjiachen.github.io) *
面包屑的最后一级是指向当前页面,那么我们自然可以将这一级面包屑与route做映射,这里采取的是将route中的信息存到sessionStorage,storage中存的是当前所有面包屑的信息,如下图
对应的面包屑
对应代码如下
getBreadCrumb() {
const { path, params, query, redirect, meta } = this.$route
// matched 包含当前当前路由的所有父层级(祖先层级)
const matched = this.$route.matched.filter(
item => item.meta && item.meta.title && item.meta.breadcrumb !== false
).slice()
let breadCrumbs = sessionStorage.getItem('breadCrumb')
if (!breadCrumbs) {
breadCrumbs = []
} else {
breadCrumbs = JSON.parse(breadCrumbs)
}
// 思路 breadCrumbs是上一次面包屑 与当前路由的matched 做比较 找到index相同但是 path不同的 索引,说明当前面包屑应该由
// breadCrumbs与matched从第一级开始 连续相同的部分(breadCrumbs中有query等,取这部分) + matched中剩余的部分(去掉与breadCrumbs相同的部分(没有经过此页,但面包屑需要),去掉matched最后一项) + 当前路由
let criticalIndex = matched.findIndex((item, index) => {
return !breadCrumbs[index] || item.path !== breadCrumbs[index].path
})
if (criticalIndex === -1) {
criticalIndex = matched.length
}
const temp = matched.slice(criticalIndex, matched.length).map(item => ({ path: item.path, params: item.params, query: item.query, redirect: item.redirect, meta: item.meta }))
breadCrumbs = breadCrumbs.slice(0, criticalIndex).concat(...temp)
breadCrumbs[breadCrumbs.length - 1] = { path, params, query, redirect, meta }
sessionStorage.setItem('breadCrumb', JSON.stringify(breadCrumbs))
this.levelList = breadCrumbs
}
不足
如果某级面包屑不经过它的父级而可直接跳转到它的子级,那么无法记录它的参数,这点需要与产品谈,这是面包屑跳转的必然问题,无法解决(当初产品死活要面包屑跳转功能,建议跟产品沟通,最好不要面包屑跳转功能,给个tab按钮其实也可达到目的)