本文只介绍垂直布局(默认)下当菜单折叠(collapse)时,鼠标hover时出现Maximum call stack size exceeded的报错,若mode="horizontal"(水平布局)的报错可以参考下面两篇文章https://blog.csdn.net/qq_31126175/article/details/81875468
https://blog.csdn.net/qq_34172153/article/details/105177925
首先放上递归的代码,父组件:
<el-menu>
<menuTree :menuTreeItem="item" v-for="item in menuTreeList" :key="item.id" />
</el-menu>
父组件不进行逻辑处理,全部放到子组件中:
<template>
<el-submenu v-if="menuTreeItem.children" :index="menuTreeItem.id">
<span slot="title">{{ menuTreeItem.name }}</span>
<el-menu-item-group>
<menuTree v-for="item in menuTreeItem.children" :key="item.id" :menuTreeItem="item" />
</el-menu-item-group>
</el-submenu>
<el-menu-item v-else :index="menuTreeItem.id">
<span slot="title">{{ menuTreeItem.name }}</span>
</el-menu-item>
</template>
这里只给出简化的代码,其他个人性需求可以自己加
菜单生成后,如果需要折叠可以加上属性:collapse="model",折叠后如果鼠标放到菜单上,就会出现以下错误:
Uncaught RangeError: Maximum call stack size exceeded.
at VueComponent.handleMouseenter (index.js:1)
at invokeWithErrorHandling (vue.js:1863)
at HTMLLIElement.invoker (vue.js:2188)
at HTMLLIElement.original._wrapper (vue.js:7547)
at VueComponent.handleMouseenter (index.js:1)
at invokeWithErrorHandling (vue.js:1863)
at HTMLLIElement.invoker (vue.js:2188)
at HTMLLIElement.original._wrapper (vue.js:7547)
at VueComponent.handleMouseenter (index.js:1)
at invokeWithErrorHandling (vue.js:1863)
此时就需要在递归的最外层加上一层div,如下:
<template>
<div>
<el-submenu v-if="menuTreeItem.children" :index="menuTreeItem.id">
<span slot="title">{{ menuTreeItem.name }}</span>
<el-menu-item-group>
<menuTree v-for="item in menuTreeItem.children" :key="item.id" :menuTreeItem="item" />
</el-menu-item-group>
</el-submenu>
<el-menu-item v-else :index="menuTreeItem.id">
<span slot="title">{{ menuTreeItem.name }}</span>
</el-menu-item>
</div>
</template>
但是菜单栏的title文字和右边的折叠箭头会出现,加入以下样式把它们隐藏即可:
.el-menu--collapse > div > .el-submenu > .el-submenu__title span {
height: 0;
width: 0;
overflow: hidden;
visibility: hidden;
display: inline-block;
}
.el-menu--collapse > div > .el-submenu > .el-submenu__title .el-submenu__icon-arrow {
display: none;
}