Vue组件之间的循环引用,你知道吗?

举报
前端老实人 发表于 2021/12/17 09:41:44 2021/12/17
【摘要】 什么是组件:众所周知组件是Vue.js最强大的功能之一。组件可以扩展HTML元素,封装可重用的代码。在较高层面上,组件是自定义的元素,Vue.js的编译器为它添加特殊功能。在有些情况下,组件也可以是原生HTML元素的形式,以is特性扩展。 循环引用 递归组件组件是可以在它们自己的模板中调用自身的,不过它们只能通过name选项来做这件事:name: 'my-cmp'不过当使用 Vue.com...

什么是组件:

众所周知组件是Vue.js最强大的功能之一。组件可以扩展HTML元素,封装可重用的代码。在较高层面上,组件是自定义的元素,Vue.js的编译器为它添加特殊功能。在有些情况下,组件也可以是原生HTML元素的形式,以is特性扩展。

循环引用

递归组件

组件是可以在它们自己的模板中调用自身的,不过它们只能通过name选项来做这件事:

name: 'my-cmp'

不过当使用 Vue.component 全局注册一个组件时,全局的ID会自动设置为该组件的 name 选项。

Vue.component('my-cmp', {  /** */ });

稍有不慎,递归组件就可能导致无限循环:

name: 'my-cmp',
template: `<div><my-cmp /></div>`

类似上述的组件将会导致“max stack size exceeded”错误,所以要确保递归调用是条件性的 (例如使用一个最终会得到 false 的 v-if)。

组件之间的循环引用

有时,在去构建一些组件时,会出现组件互为对方的后代/祖先:

Vue.component('cmp-a', {
  template: `
    <div>
      <cmp-b></cmp-b>
    </div>
  `
})
Vue.component('cmp-b', {
  template: `
    <div>
      <cmp-a></cmp-a>
    </div>
  `
})

此时,我们使用的是全局注册组件,并不会出现悖论,但是如果使用的为局部组件就会出现悖论。

但是即使用了全局注册组件,在使用webpack去导入组件时,也会出现一个错误:Failed to mount component: template or render function not defined。

模块系统发现它需要 A,但是首先 A 依赖 B,但是 B 又依赖 A,但是 A 又依赖 B,如此往复。这变成了一个循环,不知道如何不经过其中一个组件而完全解析出另一个组件。为了解决这个问题,我们需要给模块系统一个点:“A 反正是需要 B 的,但是我们不需要先解析 B。”

beforeCreate () {
  this.$options.components.CmpB = require('./tree-folder-contents.vue').default;
}

或者,在本地注册组件的时候,你可以使用 webpack 的异步 import:

components: {
  CmpB: () => import('./tree-folder-contents.vue')
}

最后

如果对您有帮助,希望能给个👍评论/收藏/三连!

博主为人老实,无偿解答问题哦❤

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。