壹点灵心理咨询平台app
121.15MB · 2025-12-19
在 Vue.js 中,slot(插槽) 是一种强大的组件间内容分发机制,它允许父组件向子组件传递自定义内容(包括 HTML 结构、文本甚至其他组件),从而极大地增强了组件的灵活性和可复用性。 下面这个表格可以帮助你快速把握 slot 的核心分类与特点:
| 插槽类型 | 核心功能 | 语法关键词 | 适用场景 |
|---|---|---|---|
| 默认插槽 | 为组件定义一个主要的内容注入点 | <slot> | 组件只有一个可定制区域时 |
| 具名插槽 | 为组件定义多个有特定位置的内容注入点 | name属性, v-slot:name | 组件布局复杂,需要多处定制(如头部、主体、尾部) |
| 作用域插槽 | 子组件向父组件传递数据,父组件决定如何渲染 | v-slot="slotProps" | 组件的 UI 样式需自定义,但数据逻辑由子组件管理 |
slot 的存在主要是为了解决组件封装中的灵活性问题。它的核心价值体现在:
这是最基础的插槽,充当子组件的内容占位符。如果父组件提供了内容,就会替换掉 <slot>标签;如果没有提供,则显示 <slot>标签内的默认内容。
子组件定义 (ChildComponent.vue):
<template>
<div class="card">
<div class="card-header">通用卡片头</div>
<!-- 默认插槽,这里是内容区域 -->
<slot>
<p>这是后备默认内容,如果父组件不传内容,就会显示这个。</p>
</slot>
</div>
</template>
父组件使用:
<template>
<ChildComponent>
<!-- 注入自定义内容到默认插槽 -->
<h3>我是父组件传过来的标题</h3>
<p>这里是父组件定义的卡片正文内容。</p>
</ChildComponent>
</template>
当一个组件需要多个插槽时,使用具名插槽来区分。通过 name属性给插槽命名,父组件使用 v-slot:name或 #name来定向分发内容。
子组件定义 (LayoutComponent.vue):
<template>
<div class="container">
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot> <!-- 不写 name 的即是默认插槽 -->
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
</template>
父组件使用:
<template>
<LayoutComponent>
<template #header> <!-- 或 v-slot:header -->
<h1>这是页眉</h1>
</template>
<p>这段内容会自动放入默认插槽。</p>
<template #footer>
<p>这是页脚信息</p>
</template>
</LayoutComponent>
</template>
这是最强大的插槽类型。它允许子组件将数据传递给父组件,父组件可以利用这些数据来灵活定义渲染逻辑。这常用于循环渲染或数据展示组件,如表格、列表。
子组件定义 (TodoList.vue):
<template>
<ul>
<li v-for="todo in todos" :key="todo.id">
<!-- 将 `todo` 数据作为插槽的 prop 传递出去 -->
<slot :todo-item="todo">
<!-- 默认渲染方式 -->
{{ todo.text }}
</slot>
</li>
</ul>
</template>
<script>
export default {
data() {
return {
todos: [
{ id: 1, text: '学习 Vue', isCompleted: true },
{ id: 2, text: '理解 Slot', isCompleted: false }
]
}
}
}
</script>
父组件使用:
<template>
<TodoList>
<!-- 通过 `v-slot` 接收子组件传递的数据 -->
<template v-slot:default="slotProps">
<!-- slotProps 是一个对象,包含了子组件传递的所有 prop -->
<span :style="{ textDecoration: slotProps.todoItem.isCompleted ? 'line-through' : 'none' }">
{{ slotProps.todoItem.text }}
</span>
</template>
</TodoList>
</template>
在这个例子中,父组件根据子组件传来的 todo-item数据,决定是否给待办项添加删除线,实现了UI 渲染的完全自定义。
v-slot:可以缩写为 #,例如 #header。但注意,#default不能简写为 #。<slot>标签内提供有意义的默认内容,这能提升组件的健壮性。v-slot:[dynamicSlotName]。希望这份详细的解释能帮助你全面理解 Vue 中的 slot 机制!