VUE3+ANTD做左侧菜单时点击出现警告:
Maximum recursive updates exceeded in component <AMenu>. This means you have a reactive effect that is mutating its own dependencies and thus recursively triggering itself. Possible sources include component template, render function, updated hook or watcher source function.
查原因简单说就是递归出现死循环,页面崩了。
我这个动态菜单在使用MENU时使用了递归来循环children
但是怎么找都找不到比较准确的解决方案,看了好多回答,每一个人的方法都不一样。简直要抓狂。
后来冷静了下,只能用最笨的方法了,一行一行的试。
<Menu
v-model:openKeys="openKeys"
:theme="theme"
:selectedKeys="selectedKeys"
mode="inline"
style="width: 400px"
@openChange="onOpenChange"
@click="handleClick"
>
<template v-for="item in permissionStore.routes" :key="item.name">
<template v-if="!item.meta || !item.meta.hidden">
<!--没有child,子路由-->
<template
v-if="
hasOneShowingChild(item.children, item as RouteRecordRaw) &&
(!onlyOneChild.children || onlyOneChild.noShowingChildren)
"
>
<MenuItem >
<routerLink :to="item.path">
{{ item.meta?.title }}
</routerLink>
</MenuItem>
</template>
<template v-else>
<SiderbarItem :menuInfo="item" />
</template>
</template>
</template>
</Menu>
最终定位是点击父节点时,判断路由的函数:hasOneShowingChild(item.children, item as RouteRecordRaw) && (!onlyOneChild.children || onlyOneChild.noShowingChildren)这个部分导致。函数代码粘过来如下:
const onlyOneChild = ref(); // 临时变量,唯一子路由
function hasOneShowingChild(
children: RouteRecordRaw[] = [],
parent: RouteRecordRaw
) {
// 子路由集合
const showingChildren = children.filter((route: RouteRecordRaw) => {
if (route.meta?.hidden) {
// 过滤不显示的子路由
return false;
} else {
route.meta!.hidden = false;
// 临时变量(多个子路由 onlyOneChild 变量是用不上的)
onlyOneChild.value = route;
return true;
}
});
if (showingChildren.length === 0) {
onlyOneChild.value = { ...parent, path: "", noShowingChildren: true };
return true;
}
return false;
}
去掉了&&后面的(!onlyOneChild.children || onlyOneChild.noShowingChildren)这个部分,再次点击就没有警告了。
后来思考了下,其他的代码被删除一样崩溃是因为其他的比较简单,而(!onlyOneChild.children || onlyOneChild.noShowingChildren)这个部分的执行包含了过多的循环部分的执行才得出onlyOneChild,还有判断onlyOneChild的children和noShowingChildren,外加下面执行的SiderbarItem 组件里包含了递归,点击了,浏览器就崩溃了。
所以出现这种问题,基本如果不是递归的问题,那也是递归代码周边部分最复杂的部分出现的问题,尝试优化这部分代码。
如果真的找不到问题,那就用一行一行的删除这种笨办法定位。