在 Vue.js 中,<template>
标签是一个非常关键且用途广泛的语法元素。它本身不会被渲染为真实的 DOM 元素,而是一个包裹/分组内容的容器,用于组织和控制内部内容的渲染逻辑。
核心作用
<template>
标签的主要作用是:
- 逻辑分组:将多个元素组合在一起,作为一个整体进行条件渲染、列表渲染或作用域管理。
- 避免额外的 DOM 包裹:由于
<template>
不会渲染为真实 DOM,可以避免为了使用v-if
、v-for
等指令而添加不必要的包裹元素(如<div>
),从而保持 DOM 结构的简洁。 - 作用域控制:在
v-for
或v-slot
中,为内部内容提供一个清晰的作用域。
主要使用场景
1. 与 v-if
/ v-else
配合使用(条件渲染)
当需要根据条件渲染多个元素时,可以用 <template>
将它们包裹起来,避免引入额外的 DOM 节点。
<template>
<div>
<!-- ❌ 不推荐:为了使用 v-if 不得不添加一个无意义的 div -->
<div v-if="userLoggedIn">
<h2>Welcome back!</h2>
<p>Here is your dashboard.</p>
</div>
<div v-else>
<h2>Please log in.</h2>
<button>Login</button>
</div>
<!-- ✅ 推荐:使用 <template> 分组,不产生额外 DOM -->
<template v-if="userLoggedIn">
<h2>Welcome back!</h2>
<p>Here is your dashboard.</p>
</template>
<template v-else>
<h2>Please log in.</h2>
<button>Login</button>
</template>
</div>
</template>
2. 与 v-for
配合使用(列表渲染)
当需要遍历数据并渲染多个并列的元素时,<template>
可以作为 v-for
的宿主,避免创建不必要的包裹元素。
<template>
<ul>
<!-- ❌ 不推荐:每个列表项都被一个额外的 div 包裹 -->
<li v-for="item in items" :key="item.id">
<div>
<span>{{ item.name }}</span>
<span>{{ item.price }}</span>
</div>
</li>
<!-- ✅ 推荐:使用 <template> 进行分组 -->
<template v-for="item in items" :key="item.id">
<li>{{ item.name }}</li>
<li class="price">{{ item.price }}</li>
</template>
</ul>
</template>
3. 与插槽(Slots)配合使用(作用域分发)
在使用具名插槽(named slots)和作用域插槽(scoped slots)时,<template>
是传递内容和访问插槽 props
的标准方式。
<!-- 子组件 ChildComponent.vue -->
<template>
<div>
<slot name="header"></slot>
<slot :user="user" :level="user.level"></slot>
<slot name="footer" :year="currentYear"></slot>
</div>
</template>
<script>
export default {
data() {
return {
user: { name: 'Alice', level: 5 },
currentYear: 2025
}
}
}
</script>
<!-- 父组件使用 -->
<template>
<ChildComponent>
<!-- 具名插槽 -->
<template v-slot:header>
<h1>Custom Header</h1>
</template>
<!-- 默认插槽,使用作用域插槽访问 user 和 level -->
<template v-slot:default="slotProps">
<p>Welcome, {{ slotProps.user.name }}!</p>
<p>Your level is {{ slotProps.level }}.</p>
</template>
<!-- 具名插槽 + 作用域插槽 -->
<template v-slot:footer="footerProps">
<small>Copyright © {{ footerProps.year }}</small>
</template>
</ChildComponent>
</template>
4. 作为组件的根模板(单文件组件)
在 .vue
单文件组件中,<template>
标签定义了该组件的 HTML 模板结构。它是组件的“视图”部分。
<template>
<!-- 这是组件的根模板 -->
<div class="my-component">
<h1>{{ title }}</h1>
<p>{{ content }}</p>
</div>
</template>
<script>
export default {
data() {
return {
title: 'Hello',
content: 'This is a Vue component.'
}
}
}
</script>
与其他标签的区别
标签 | 是否渲染为 DOM | 主要用途 |
---|---|---|
<template> | ❌ 否 | 逻辑分组、条件/列表渲染、插槽内容、定义组件模板 |
<div> | ✅ 是 | 布局、样式、作为真实容器 |
<span> | ✅ 是 | 行内容器,用于文本样式或包裹行内元素 |
总结
<template>
标签在 Vue 中扮演着“透明容器”的角色。它的核心价值在于:
- 保持 DOM 干净:避免为实现逻辑控制而添加冗余的包裹元素。
- 提供渲染逻辑的载体:是
v-if
、v-for
、v-slot
等指令作用于多个元素时的理想选择。 - 支持高级组件通信:是实现插槽(尤其是作用域插槽)的关键语法。
一句话回答:Vue 的 <template>
标签是一个不会被渲染到页面上的逻辑容器,主要用于分组元素以配合 v-if
、v-for
实现条件或列表渲染,以及在插槽中定义内容,从而避免产生不必要的 DOM 节点,保持结构清晰。
THE END