一、错误详情
el-menu的子菜单鼠标移入时报"Maximum call stack size exceeded."错误,如下图:
二、问题研究
点进代码的错误位置可以发现问题出在了element-ui/index.js的鼠标进入事件的消息分发上,
这里handleMouseenter事件处理中再次调用了父元素的mouseenter事件方法,由此发生了无限递归导致栈溢出。
在错误的el-submenu页面输出该元素的实例查看详细情况:
根据上面这张图可以看出来el-submenu的$parent里的$el对应元素依然是自身,也因此elementui使用this.$parent.$el.displatchEvent调用事件会导致无限递归。
该情况只会出现在el-menu与el-submenu不在同一个vue页面里,并且el-submenu是新页面<template></template>里的唯一元素的情况中,一种简单的解决方法是在新页面的el-submenu外嵌套一层,但这样会导致ui不美观,因此推荐使用下面的方法。
三、解决方案
其实导致无限递归的原因无非是element想调用节点的父级事件,但vue在这种情况下节点的父级节点元素依然是自身(element真正想找的父节点其实应该是el-submenu的父节点实例(也就是该页面)的父节点(el-menu)),只要手动赋给该节点真正的父级节点即可,解决方法如下:
// 将该行代码放到能够顺利执行的地方就可以,本示例中放到了mounted中
// 由于这种错误只发生在template下只有一个el-submenu这种情况,因此this.$children[0]就是该el-submenu
this.$children[0].$parent = this.$parent
只要将该页面节点的父节点赋值给el-submenu即可,这样element在找父节点时就不会无限递归了。
鼠标再放上去也不会报错了。