递归element-ui el-menu 实现无限级子菜单
recursionMenu.vue
<template><!-- 有子菜单------------------------------------------><el-submenuv-if="(item.children || []).length":popper-class="popper_class":show-timeout="show_timeout":hide-timeout="hide_timeout":key="item.path || item.label":index="item.path || item.label":divide="item.divide"><template slot="title"><!-- 主菜单图标 --><i :class="item.icon" :style="item.style" /><!-- 主菜单文字 --><span :style="item.style">{{ item.label }}</span><el-badgev-if="item.badge":is-dot="!item.badge.value":value="item.badge.value":type="item.badge ? item.badge.type : `danger`"/></template><recursionMenuv-for="(item, i) in item.children":key="item.path || item.label":data="{item,show_timeout: show_timeout,hide_timeout: hide_timeout,popper_class: popper_class,}"/></el-submenu><!-- 没有子菜单------------------------------------------><el-menu-itemv-else:key="`leaf-${item.path || item.label}`":index="item.path || item.label":divide="item.divide"><!-- 主菜单图标 --><i :class="item.icon" :style="item.style" /><!-- 主菜单文字 --><span :style="item.style">{{ item.label }}</span><el-badgev-if="item.badge":is-dot="!item.badge.value":value="item.badge.value":type="item.badge ? item.badge.type : `danger`"/></el-menu-item>
</template>
<script>
export default {name: `recursionMenu`,components: {},data() {return {item: {},popper_class: ``,show_timeout: 300,hide_timeout: 300,};},props: ["data"],computed: {},watch: {data: {handler(newValue, oldValue) {// console.log(`深度监听${this.$options.name}:`, newValue, oldValue);if (Object.keys(newValue || {}).length) {this.form = JSON.parse(JSON.stringify(newValue));this.$g.convertForm2ComponentParam(`item`, this);this.$g.convertForm2ComponentParam(`popper_class`, this);this.$g.convertForm2ComponentParam(`show_timeout`, this);this.$g.convertForm2ComponentParam(`hide_timeout`, this);}},deep: true, //深度监听immediate: true, //立即执行},},created() {},mounted() {// 将该行代码放到能够顺利执行的地方就可以,本示例中放到了mounted中// 由于这种错误只发生在template下只有一个el-submenu这种情况,因此this.$children[0]就是该el-submenuthis.$children[0].$parent = this.$parent;},beforeDestroy() {},methods: {},
};
</script>
<style lang="scss" scoped>
.recursionMenu {
}
</style>
demo
<template><div :class="$options.name"><el-menu:class="$options.name":collapse="collapse":default-active="default_active":default-openeds="default_openeds":mode="mode"@select="select"><recursionMenuv-for="(item, i) in menu":key="i":data="{item,show_timeout: show_timeout,hide_timeout: hide_timeout,popper_class: `admin_v2-top-submenu${collapse ? `-collapse` : ``}`,}"/></el-menu></div>
</template>
<script>
import recursionMenu from "@/vue/admin/recursionMenu";
export default {name: `topMenu`,components: { recursionMenu },data() {return {collapse: null,default_active: null,default_openeds: [], //默认展开的菜单index数组menu: [],mode: `horizontal`,select: null,show_timeout: 300,hide_timeout: 300,};},props: ["data"],computed: {},watch: {data: {handler(newValue, oldValue) {// console.log(`深度监听${this.$options.name}:`, newValue, oldValue);if (Object.keys(newValue || {}).length) {let select = newValue.select;this.select = select;delete newValue.select;this.form = JSON.parse(JSON.stringify(newValue));this.$g.convertForm2ComponentParam(`isSubMenu`, this);this.$g.convertForm2ComponentParam(`collapse`, this);this.$g.convertForm2ComponentParam(`default_active`, this);this.$g.convertForm2ComponentParam(`default_openeds`, this);this.$g.convertForm2ComponentParam(`menu`, this);this.$g.convertForm2ComponentParam(`mode`, this);this.$g.convertForm2ComponentParam(`show_timeout`, this);this.$g.convertForm2ComponentParam(`hide_timeout`, this);}},deep: true, //深度监听immediate: true, //立即执行},navList: {handler(newValue, oldValue) {//console.log(`深度监听${this.$options.name}:`, newValue, oldValue);if (Object.keys(newValue || {}).length) {this.collapse_navList = [{label: `菜单`,icon: "el-icon-menu",// ID: "MENU-ROOT",// "PID": "SRManagePermissions",// "leaf": false,children: this.navList,},];}},deep: true, //深度监听immediate: true, //立即执行},},created() {},mounted() {},beforeDestroy() {},methods: {},
};
</script>
<style lang="scss" scoped>
.topMenu {>>> .el-menu {background-color: transparent;$menu-height: 50px;.el-icon-menu {color: white;}$active-background: radial-gradient(100% 80% at 50% 100%, #ffffff66, transparent 50%);.el-menu-item,.el-submenu__title {height: $menu-height;line-height: revert;display: flex;justify-content: center;align-items: center;padding: 0 10px;color: white !important;border-bottom: none !important;transition: none;// 选中菜单、聚焦菜单、移入菜单&.is-active,&:focus,&:hover {background: $active-background;}}// 有子菜单的.el-submenu__title {cursor: default;}.el-submenu {&.is-active {& > .el-submenu__title {background: $active-background;}}}.el-submenu__icon-arrow {display: none;}}
}
</style>
<style lang="scss">
.admin_v2-top-submenu,
.admin_v2-top-submenu-collapse {transition: none !important; //去掉下拉菜单动画transform: translateX(-10px);// 有子菜单的.el-submenu__title {cursor: default;}.el-menu-item {display: flex;justify-content: center;align-items: center;padding: 0 20px !important;transition: none;&.is-active {pointer-events: none;background-color: #409eff !important;color: white !important;}&:hover {background-color: #ecf5ff;color: #66b1ff !important;}}
}
.admin_v2-top-submenu-collapse {.el-menu-item {justify-content: flex-start;}.el-submenu {padding: 0 20px;.el-menu-item {min-width: revert;}.el-submenu__title {display: flex;align-items: center;padding: 0 !important;.el-submenu__icon-arrow {position: static;margin-top: revert;margin-left: 10px;}}&.is-active {background-color: #409eff;& > .el-submenu__title {background-color: transparent;& > * {color: white;}}}}
}
</style>
解决报错el-menu子菜单鼠标移入报“Maximum call stack size exceeded.“错误原因及解决方法-CSDN博客文章浏览阅读25次。【代码】el-menu子菜单鼠标移入报“Maximum call stack size exceeded.“错误原因及解决方法。https://blog.csdn.net/qq_37860634/article/details/147758875