When the submenu of the navigation bar is generated in recursive mode, the menu can be generated normally, but when the mouse hover is used, a loop call (mouseenter) event will occur, resulting in an error in the end
How to deal with it
Note: In version 2.13.2, you only need to set the attributes of the submenu:popper-append-to-body="false" to the submenu and this problem will not occur.
The error message is as follows:
Uncaught RangeError: Maximum call stack size exceeded.
at (:1)
at invokeWithErrorHandling (:1863)
at (:2188)
at ._wrapper (:7547)
at (:1)
at invokeWithErrorHandling (:1863)
at (:2188)
at ._wrapper (:7547)
at (:1)
at invokeWithErrorHandling (:1863)
Test code
Version:
- vue: v2.6.11
- element-ui: 2.13.0
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <!-- Introduce styles --> <link rel="stylesheet" href="/element-ui/lib/theme-chalk/" rel="external nofollow" > </head> <body> <div > <el-menu mode="horizontal"> <template v-for="(menu,index) in menus"> <sub-menu v-if=" && " :key="index" :item="menu"></sub-menu> <el-menu-item v-else :index="" :key="index">{{ }}</el-menu-item> </template> </el-menu> </div> <script src="/npm/vue/dist/"></script> <!-- Introducing component library --> <script src="/element-ui/lib/"></script> <script type="text/javascript"> ('sub-menu', { props: ['item'], template: ` <el-submenu :index=""> <template slot="title"> {{}} </template> <template v-for="(child,index) in "> <sub-menu v-if="" :item="child" :key="index"></sub-menu> <el-menu-item v-else :key="index" :index=""> {{}} </el-menu-item> </template> </el-submenu> ` }) let vm = new Vue({ el: '#root', data() { return { menus: [{ title: 'My workbench', path: '2', children: [{ title: 'Option 1', path: '2-1' }, { title: 'Option 2', path: '2-2', }, ], },{ title:'Background Management', path:'3' }] } }, components: {} }) </script> </body> </html>
Error analysis
Observe the navigation bar code and error code generated by recursively:
handleMouseenter: function(e) { var t = this , i = > 1 && void 0 !== arguments[1] ? arguments[1] : ; if ("ActiveXObject"in window || "focus" !== || ) { var n = , r = ; "click" === && "horizontal" === || ! && "vertical" === || r || (("ElSubmenu", "mouse-enter-child"), clearTimeout(), = setTimeout(function() { (, ) }, i), && this.$parent.$(new MouseEvent("mouseenter")));//Report an error code } },
It is speculated that the elements are repeatedly dispatched and accepted by mouseenter events because of the bubble or sinking of events, which has caused a state similar to a dead loop. Due to time constraints, I did not go into it in depth. I will check the root cause when I have time later (if I remember...)
When the mouse is moved into the menu, the handleMouseenter method is triggered, but because appendToBody is true, the mouse move-in event is dispatched, and then it returns to this method, which creates a dead loop. appendToBody is a computed property, so why is appendToBody true? Look at the code:
{ name: 'ElSubmenu', componentName: 'ElSubmenu', props:{ popperAppendToBody: { type: Boolean, default: undefined } }, computed:{ appendToBody() { return === undefined ? // When the specified popperAppendToBody is not displayed, calculate this value : ; }, isFirstLevel() { let isFirstLevel = true; let parent = this.$parent; while (parent && parent !== ) { //Calculate whether the first level menu is currently on. //It seems that there is no problem, because the code already indicates that the current component name is componentName: 'ElSubmenu', but it was found during debugging that the value of componentName is Undefined, so no matter which level it is, the final result is isFirstLevel = true if (['ElSubmenu', 'ElMenuItemGroup'].indexOf(parent.$) > -1) { isFirstLevel = false; break; } else { parent = parent.$parent; } } return isFirstLevel; } } }
As for why vue did not collect this parameter when registering the component, it also needs to look at the source code. After lunch break, I have to continue to use the code... I will analyze it if I have time...
How to deal with it
Add a property to el-submenu:popper-append-to-body="true false" explicitly specify that appendToBody is false
Special apology:
The previous processing method was written incorrectly, and it was written as: popper-append-to-body="true". Therefore, even if this attribute is added, it still reports an error. I apologize here!
This is the article about detailed explanation of the use of errors when using the Element-ui NavMenu submenu to generate the Element-ui NavMenu submenu. This is the end of this article. For more related contents of the Element-ui NavMenu submenu to generate the Element-ui NavMenu submenu, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!