1、Vue2 结合 ElementUI 重复点击 Menu 报错的解决方案
- 1.1 在使用 Vue2 和 ElementUI 开发应用程序时,经常会遇到重复点击菜单(Menu)时出现报错的情况。具体报错信息可能会因为不同的代码实现而有所不同,但是通常都与 Vue 的 $nextTick() 方法有关。下面将介绍这个问题的背景和解决方案。
2、问题背景
-
2.1 ElementUI 的菜单(Menu)组件是 Vue 的子组件,它会在父组件中渲染。当菜单中的某一项被点击时,会触发父组件中的相应方法,这个方法中通常会进行一些异步操作。如果用户在这个异步操作没有完成之前快速多次点击菜单,就有可能出现问题。
-
2.2 具体来说,问题出现在 Vue 的异步更新机制中。Vue 中的 $nextTick() 方法用于在 DOM 更新之后执行代码,它会在下一个 DOM 更新周期中执行传入的回调函数。而当用户在菜单项被点击后快速多次点击菜单时,可能会导致多个回调函数同时被加入到 Vue 的更新队列中,这就会导致 $nextTick() 方法被多次调用,从而出现报错。
3、解决方案
- 3.1 禁用菜单.当用户点击菜单时,可以在异步操作完成之前禁用整个菜单,这样就可以避免用户在异步操作未完成时继续点击菜单。
<el-menu :default-active="activeIndex" @select="handleSelect" :collapse="collapse">
<template v-if="!loading">
<!-- 菜单内容 -->
</template>
<template v-else>
<el-menu-item disabled>
<i class="el-icon-loading"></i>
</el-menu-item>
</template>
</el-menu>
在这个例子中,当 loading 为 true 时,整个菜单会被禁用,并显示一个 loading 图标。当异步操作完成后,将 loading 置为 false 即可恢复菜单。
- 3.2 在销毁菜单之前手动移除 deselect 事件监听器
beforeDestroy() {
this.$refs.menu.$off('deselect')
}
- 3.3 在销毁菜单之前判断菜单是否已经被销毁
beforeDestroy() {
if (this.$refs.menu && this.$refs.menu.$el) {
this.$refs.menu.$off('deselect')
}
}