面包屑、tagsView、菜单联动
前言
整体思路:
sideBar左侧菜单与面包屑、tagsView产生联动关系重点在于节点的标识(key,pkey–所有父节点key生成的一个数组)以及父节点的标识(key),所以当从后台拿到数据先要通过递归遍历的方法对数据进行改造。
通过点击菜单收集当前菜单数组所有的key组成一个新的数组["1","1.1","1.1.1"]
然后再通过递归遍历的方法去找到所有key对应的路由信息并组成一个新的数组[{},{},{}]
,然后通过mapstate采集到数据currentRouteArr
去view层展示,这样做的方式是为了后期更容易扩展。之前也网上找了很多思路但大多是阉割版。
点击菜单收集路由信息到state,然后展示对应的tagsview,点击tag与上同理,可封装成一个公共方法去调用。找到所有的key,这个key在你构造数据的时候就已经处理好了,在稍加处理即可[...item.key,...item.pkey]
。这个重点在于修改currentRouteArr
与visitRoutes
。currentRouteArr
是为了高亮显示当前点击的tag、联动面包屑,visitRoutes
是为了更新访问的路由列表。在关闭tag时需要获取到当前的路由信息,如果点击的是访问的路由列表中间的一项那就跳转index+1
的路由,再去修改currentRouteArr
,如果点击的是最后一项那就跳转index-1
的路由,再去修改currentRouteArr
,这里修改currentRouteArr
是为了联动面包屑。
那点击tag或者关闭tag如何去联动菜单,在这里不仅仅需要修改currentRouteArr
,在进行这些操作后还需要修改菜单的selectedKey
,openKeys
(我用的是ui是ant-design-vue)
大体思路就是这样,只有深入其中才能更好的理解,如果各位有更好的思路可以纠正
上述三者的主要代码
1.路由列表改造添加key,pkey
代码如下(示例):
function dealRouterList(arr, parentKey = 0, pkeyArr = 0) {
arr.forEach((item, index) => {
item.key = index + 1 + "";
if (parentKey !== 0) {
item.key = parentKey + "." + (index + 1) + "";
if (pkeyArr !== 0) {
if (pkeyArr.indexOf(",") !== -1) {
item.pkey = pkeyArr.split(",");
} else {
item.pkey = [pkeyArr];
}
}
}
if (item.children) {
let pkeyArr = [];
if (item.pkey) {
pkeyArr = item.key + "," + item.pkey;
} else {
pkeyArr = item.key;
}
dealRouterList(item.children, item.key, pkeyArr);
}
});
}
2.visitViews–作用于tagsview
2.1添加visitViews
代码如下(示例):
let hasPush = state.visitedViews.find((item) => {
return data.path === item.path;
});
if (!hasPush) {
state.visitedViews.push(data);
}
2.2close删除tag
代码如下(示例)
this.selectKeysArr = [];
this.selectKeys = [];
let currentIndex = this.tags.findIndex((item) => {
return tag.path === item.path;
});
let currentRouteObj;
if (currentIndex === this.tags.length - 1) {
//最后一个
currentRouteObj = this.tags[this.tags.length - 2];
} else {
currentRouteObj = this.tags[currentIndex + 1];
}
//更改当前选中的菜单
this.findSelectkeysObj(currentRouteObj, routerList);
this.$store.dispatch("tagsView/selectKeysArr", this.selectKeysArr);
//删除记录的tagViews
this.$store.dispatch("tagsView/closeThisMenu", currentIndex).then(() => {
this.$router.push(currentRouteObj.path);
bus.$emit("closeTag", currentRouteObj);
});
3.currentRouteArr–作用于面包屑
代码如下(示例):
Vue.prototype.findSelectkeysObj = function (route, routes) {
if (this.selectKeys.length === 0) {
if (route.pkey) this.selectKeys.push(...route.pkey);
this.selectKeys.push(route.key);
}
this.selectKeys.forEach((item) => {
routes.forEach((citem) => {
if (item === citem.key) {
this.selectKeysArr.push(citem);
if (citem.children) {
this.findSelectkeysObj(route, citem.children);
}
}
});
});
};