Vue 组件循环嵌套引用问题

项目开发中,经常会出现组件之间循环嵌套的问题,下面我们以 Element-Ui 中的 NavMenu导航菜单组件二次封装为例。暂不考虑 el-menu-item-group 的问题,将 NavMenu 拆分成如下的几个小组件。

一、组件代码

menu-item

menu-item为原导航菜单组件的el-menu-item,大致代码如下:

<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

sub-menu为原导航菜单组件的el-submenu,大致代码如下:

<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>

nav-menu

nav-menu为原导航菜单组件的el-menu

<template>
  <el-menu class="nav-menu">
    <template v-for="(menu, index) in menus">
      <sub-menu
        v-if="menu.subMenu && menu.subMenu.length"
        :menu="menu"
        :key="`sub-menu-${index}`"
      />
      <menu-item v-else :menu="menu" :key="`menu-item-${index}`" />
    </template> </el-menu
></template>
<script>
  import MenuItem from './menu-item.vue'
  import SubMenu from './sub-menu.vue'
  export default {
    props: {
      menus: Array
    },
    components: {
      MenuItem,
      SubMenu
    }
  }
</script>

二、组件调用

<template>
  <nav-menu :menus="menus"/>
</template>
<script>
  import NavMenu from '@/components/nav-menu/nav-menu'
  export default {  
    components: {    NavMenu  },  
    data () {
      return {
        menus: [
          { label: "菜单1", menuName: "1", path: "" },
          {
            label: "菜单2",
            menuName: "2",
            subMenu: [
              { label: "菜单2-1", menuName: "2-1", path: "" },
              {
                label: "菜单2-2",
                menuName: "2-2",
                subMenu: [{ label: "菜单2-2-1", menuName: "2-2-1", path: "" }],
              },
            ],
          },
          { label: "菜单3", menuName: "3" },
        ],
      }
    }
  }
</script>

三、出现报错情况

image

然后就会出现一个组件未注册的报错情况,然后仔细查代码,看不是否有menu-item拼错了,发现没有,都是对的,每次刷新页面都会报这个错误,导致子集菜单不显示。最后用排除大法,将menu-item中的sub-menu注释掉后该报错没有了,目测问题应该是出现在这儿,但是sub-menu也没啥问题啊,百思不得其解,Google了半天才找到答案。

四、总结

归根结底还是组件之间的循环引用造成的问题,正如上面的链接所说的,有两个组件称为 A 和 B(A、B就相当于这里的 menu-itemsub-menu )。模块系统发现它需要 A,但是首先 A 依赖 B,但是 B 又依赖 A,但是 A 又依赖 B,如此往复。这变成了一个循环,不知道如何不经过其中一个组件而完全解析出另一个组件。官方给的解决方法就是异步加载组件。将上面的 import 加载的方式全部变成异步加载,代码如下:

const MenuItem = () => import('./menu-item.vue')
const SubMenu = () => import('./sub-menu.vue')

测试下了果然报错就没了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,445评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,889评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,047评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,760评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,745评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,638评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,011评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,669评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,923评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,655评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,740评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,406评论 4 320
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,995评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,961评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,023评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,483评论 2 342

推荐阅读更多精彩内容