Skip to content

动态组件

有的时候,在不同组件之间进行动态切换是非常有用的,比如在一个多标签的界面里:

上面的例子是通过 Vue 的 <component> 元素和特殊的 is attribute 实现的:

template
<!-- currentTab 改变时组件也改变 -->
<component :is="currentTab"></component>
template
<!-- currentTab 改变时组件也改变 -->
<component :is="tabs[currentTab]"></component>

在上面的例子中,被传给 :is 的值可以是以下几种:

  • 被注册的组件名
  • 导入的组件对象

你也可以使用 is attribute 来创建一般的 HTML 元素。

当在 <component :is="..."> 上使用时,被切换掉的组件会被卸载。我们可以通过 <KeepAlive> 组件强制被切换掉的组件仍然保持"存活"的状态。

DOM 内模板解析注意事项

如果你想在 DOM 中直接书写 Vue 模板,Vue 则必须从 DOM 中获取模板字符串。由于浏览器的原生 HTML 解析行为限制,有一些需要注意的事项。

TIP

请注意下面讨论只适用于直接在 DOM 中编写模板的情况。如果你使用来自以下来源的字符串模板,就不需要顾虑这些限制了:

  • 单文件组件
  • 内联模板字符串 (例如 template: '...')
  • <script type="text/x-template">

大小写不敏感

HTML 标签和属性名称是不分大小写的,所以浏览器会把任何大写的字符解释为小写。这意味着当你使用 DOM 内的模板时,无论是 PascalCase 的组件名称、camelCase 的 prop 名称还是 v-on 的事件名称,都需要转换为相应等价的 kebab-case (短横线连字符) 形式:

js
// 在 JavaScript 中是 camelCase 的
const BlogPost = {
  props: ['postTitle'],
  emits: ['updatePost'],
  template: `
    <h3>{{ postTitle }}</h3>
  `
}
template
<!-- 在 HTML 中是 kebab-case 的 -->
<blog-post post-title="hello!" @update-post="onUpdatePost"></blog-post>

闭合标签

我们在前面的例子中已经使用过了闭合标签 (self-closing tag):

template
<MyComponent />

这是因为 Vue 的模板解析器支持任意标签使用 /> 作为标签关闭的标志。

然而在 DOM 内模板中,我们必须显式地写出关闭标签:

template
<my-component></my-component>

这是由于 HTML 只允许一小部分特殊的元素省略其关闭标签,最常见的就是 <input><img>。对于其他的元素来说,如果你省略了关闭标签,原生的 HTML 解析器会认为开启的标签永远没有结束,用下面这个代码片段举例来说:

template
<my-component /> <!-- 我们想要在这里关闭标签... -->
<span>hello</span>

将被解析为:

template
<my-component>
  <span>hello</span>
</my-component> <!-- 但浏览器会在这里关闭标签 -->

元素位置限制

某些 HTML 元素对于放在其中的元素类型有限制,例如 <ul><ol><table><select>,相应的,某些元素仅在放置于特定元素中时才会显示,例如 <li><tr><option>

这将导致在使用带有此类限制元素的组件时出现问题。例如:

template
<table>
  <blog-post-row></blog-post-row>
</table>

自定义的组件 <blog-post-row> 将作为无效的内容被忽略,因而在最终呈现的输出中造成错误。我们可以使用特殊的 is attribute 作为一种解决方案:

template
<table>
  <tr is="vue:blog-post-row"></tr>
</table>

TIP

当使用在原生 HTML 元素上时,is 的值必须加上前缀 vue: 才可以被解析为一个 Vue 组件。这样做是为了避免和原生的自定义内置元素相混淆。

以上就是你需要了解的关于 DOM 内模板解析的所有注意事项,同时也是 Vue 基础的结尾。祝贺你!虽然还有很多需要学习的,但你可以先暂停一下,去用 Vue 构建一些有趣的东西。

完成了本页的阅读后,回顾一下你刚才所学到的知识,如果还有哪些地方不太清楚,你可以重新阅读一遍。当你准备好了解更多关于 Vue 的深入功能时,我们推荐继续阅读关于组件的完整指引。

基于 Vue.js 官方文档构建的学习宝典