在工作中,遇到一个循环调用的场景,需要用到父组件调用子组件。在子组件中,再循环调用父组件。
代码类似这样的:
menu-item.vue
<template>
<div class="meun-item">
<sub-menu v-if="menu.subMenu && menu.subMenu.length"
:menu="menu" />
<router-link v-else
:to="menu.path">
<el-menu-item :index="menu.menuName"
:disabled="!!menu.disabled">
<template slot="title">
<i v-if="menu.icon"
:class="['iconfont', menu.icon]"></i>
<span class="menu-text">{ { menu.label }}</span>
</template>
</el-menu-item>
</router-link>
</div>
</template>
<script>
import SubMenu from './sub-menu.vue'
export default {
props: {
menu: Object
},
components: {
SubMenu
}
}
</script>
sub-menu.vue
<template>
<el-submenu :index="menu.menuName">
<template slot="title">
<i v-if="menu.icon" :class="['iconfont', menu.icon]"></i>
<span class="menu-text">{ { menu.label }}</span>
</template>
<menu-item v-for="(item, index) in menu.subMenu || []" :menu="item" :key="index" />
</el-submenu>
</template>
<script>
import MenuItem from './menu-item.vue'
export default {
name: 'SubMenu',
props: {
menu: Object
},
components: {
MenuItem
}
}
</script>
之后就一直报组件未定义,各种检查都没问题,考虑到应该是组件循环嵌套的问题。
谷歌百度整了半天,终于找到了解答。组件之间的循环引用
总结
归根结底还是组件之间的循环引用造成的问题,正如上面的链接所说的,
有两个组件称为 A 和 B(A、B就相当于这里的menu-item
和sub-menu
)。
模块系统发现它需要 A,但是首先 A 依赖 B,但是 B 又依赖 A,但是 A 又依赖 B,如此往复。
这变成了一个循环,不知道如何不经过其中一个组件而完全解析出另一个组件。
官方给的解决方法就是异步加载组件。
改变引用方式,将上面的import
加载的方式全部变成异步加载,如下
components: {
MenuItem: () => import('./menu-item.vue')
}