submenu在结合路由使用时刷新页面,导致submenu的展开状态丢失
发表于:2023-08-31 |

问题描述

element-ui的submenu结合路由时会刷新页面,导致submenu的展开状态丢失,其他UI库也有类似的问题,可统一解决,具体问题可看以下视频左侧菜单栏的状态

解决思路

使用下拉菜单栏自定义的展开状态,来控制菜单栏的展开状态,这样就不会因为刷新页面而导致菜单栏的展开状态丢失了,根据element ui的官方文档,el-menu的状态通过default-openeds属性即可改变,因此只需要改变default-openeds就可以了

个人踩坑

我一开始把default-openeds依托的属性写在了和el-menu同一个文件里,然后因为切换路由导致的页面刷新,我的展开路由的状态就一直重置了,后来我把default-openeds依托的属性写在了vuex里,这样就不会因为切换路由导致的页面刷新而导致我的展开路由的状态重置了

代码实现

先在store中定义一下state和mutations

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const state = {
expandUserMenu: []
}

const mutations = {
editExpandUserMenu(state, payload) {
state.expandUserMenu = payload
}
}

export default {
namespaced: true,
state,
mutations,
}

然后在menu的组件中

html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<el-menu
background-color="#fff"
text-color="#000"
active-text-color="#8B0505"
:collapse="isCollapse"
:collapse-transition="false"
:default-openeds="expandUserMenu"
:default-active="activePath"
@close="handleClose"
@open="handleOpen"
router
>
xxxxx
</el-menu>

方法

这里我用了closeTime避免关闭的时候触发了因为activePath的改变而导致的handleOpen方法的调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
handleClose(val) {
const data = [...this.expandUserMenu];
const newData = data.filter((item) => {
return item !== val;
});
this.closeTime = true;
this.$store.commit("info/editExpandUserMenu", newData);
},
handleOpen(path) {
if (this.closeTime) {
return;
}
// 判断是否在需要展开的路由中
const index = this.possibleOpenRouter.findIndex((item) => {
return item.children.some((item) => {
return item.route === path;
});
});
if (~index) {
const currentRoute = this.possibleOpenRouter[index];
const data = [...this.expandUserMenu];
if (!data.includes(currentRoute.route)) {
data.push(currentRoute.route);
this.$store.commit("info/editExpandUserMenu", data);
}
}
},

计算属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
computed: {
activePath() {
const route = this.$route;
const { meta, path } = route;
if (meta.activeMenu) {
return meta.activeMenu;
}
this.handleOpen(path);
return path;
},

possibleOpenRouter() {
return this.userCenterList.filter((item) => {
return item.children && item.children.length > 0;
});
},
expandUserMenu() {
return this.$store.state.info.expandUserMenu;
},
},

最终效果

结语

本文就到这里了,再见

上一篇:
【可视化学习】35-根据已有模型渲染智慧园区
下一篇:
【可视化学习】34-根据户型数据渲染全景房