跳到主要内容

Vue.js 插槽与作用域插槽

在构建 Vue 组件时,有时你会希望组件更具灵活性,让父组件可以传入特定内容。这个时候,“插槽(Slots)”就派上了用场。本节你将学会如何使用普通插槽和作用域插槽,让你的组件更具复用性与可配置性。

什么是插槽?

插槽(Slots)是 Vue 提供的一种内容分发机制,允许你在子组件中预留一些位置,由父组件填充内容。就像 HTML 标签的“内容部分”一样,插槽允许父组件自定义传入的结构,而不是被动接受固定的子组件布局。

默认插槽

默认插槽是最常见的一种插槽使用方式。你只需在子组件的模板中添加 <slot /> 标签,父组件就可以向里面填入内容。

子组件:BaseCard.vue

BaseCard.vue
<template>
<div class="card">
<slot />
</div>
</template>

父组件使用:

App.vue
<BaseCard>
<h2>标题</h2>
<p>这是卡片的内容。</p>
</BaseCard>

在渲染时,这些内容会替换掉 <slot /> 所在的位置。

具名插槽

当你有多个插槽时,可以使用具名插槽来区分不同的内容区域。

子组件:

BaseCard.vue
<template>
<header><slot name="header" /></header>
<main><slot /></main>
<footer><slot name="footer" /></footer>
</template>

父组件使用:

App.vue
<BaseCard>
<template #header>
<h1>自定义标题</h1>
</template>

<p>正文内容。</p>

<template #footer>
<small>页脚信息</small>
</template>
</BaseCard>
提示

你也可以使用 v-slot:header 替代 #header,它们是等价的。

作用域插槽

作用域插槽(Scoped Slots)允许子组件向插槽传递数据,让父组件可以动态使用这些数据。你可以把它理解为“从子组件提供数据,由父组件决定如何渲染”。

示例:展示用户列表

子组件:UserList.vue

UserList.vue
<template>
<ul>
<li v-for="user in users" :key="user.id">
<slot :user="user" />
</li>
</ul>
</template>

<script setup>
const users = [
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' }
]
</script>

父组件使用:

App.vue
<UserList>
<template #default="{ user }">
<strong>{{ user.name }}</strong>
</template>
</UserList>

这样一来,你就可以自由定义每个用户项的渲染方式。

提示

你也可以写成 v-slot="{ user }",用的是相同的语法原理。

简写语法

你可以用简写方式来绑定具名插槽和作用域插槽:

<!-- 完整写法 -->
<template v-slot:header>...</template>

<!-- 简写 -->
<template #header>...</template>

<!-- 默认作用域插槽的简写 -->
<UserList v-slot="{ user }">...</UserList>

插槽的默认内容

你也可以给插槽设置默认内容,以防父组件没有传入内容:

<slot>默认内容</slot>

这在构建可复用组件时特别有用。

使用注意事项

  • 插槽只能用于子组件模板中;
  • 一个组件可以包含多个具名插槽;
  • 作用域插槽默认绑定在 <slot> 元素上,不影响组件的响应式;
  • 插槽不是跨组件通信的方式,仅用于结构内容的插入与渲染控制。

小结

插槽让你可以在子组件中预留结构位置,由父组件自由插入内容;作用域插槽则进一步提升灵活性,让子组件提供数据,父组件决定内容如何呈现。掌握插槽机制后,你就能构建出更具扩展性和复用性的 Vue 组件结构。建议你在实际项目中多尝试应用插槽,会有不少收获!

知心 MBTI 微信小程序
「知心MBTI」微信小程序,探索你的 MBTI 人格类型,发现潜能。微信扫码免费测试 🎉