模式切换
插槽(Slots)
插槽(Slots)是 Vue 组件化开发的核心功能之一,用于实现内容分发,允许父组件向子组件注入动态内容。
默认插槽
作用
- 子组件预留一个位置,由父组件传入任意内容(文本、HTML、其他组件)。
语法
子组件定义插槽:
html
<!-- ChildComponent.vue -->
<template>
<div class="card">
<slot>默认内容(父组件未传内容时显示)</slot>
</div>
</template>
父组件传递内容:
html
<ChildComponent>
<p>这是父组件插入的内容</p>
</ChildComponent>
特点
- 如果父组件不提供内容,会显示
<slot>
标签内的默认内容。 - 支持任何合法的模板代码(包括其他组件)。
具名插槽
作用
- 子组件定义多个插槽位置,父组件按名称定向分发内容。
语法
子组件定义具名插槽:
html
<!-- ChildComponent.vue -->
<template>
<div class="layout">
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot> <!-- 默认插槽 -->
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
</template>
父组件传递具名内容:
- 使用
v-slot:name
或缩写#name
指定插槽
html
<ChildComponent>
<template #header>
<h1>这是标题</h1>
</template>
<p>这是默认插槽的内容</p>
<template #footer>
<button>保存</button>
</template>
</ChildComponent>
特点
- 未命名的内容会自动分配到默认插槽。
v-slot
只能用在<template>
或组件上。
作用域插槽
作用
- 子组件向父组件传递数据,父组件决定如何渲染。
- 常见场景:封装可复用的数据列表组件。
语法
子组件暴露数据:
html
<!-- ChildList.vue -->
<template>
<ul>
<li v-for="item in items" :key="item.id">
<slot :item="item" :index="$index"></slot>
</li>
</ul>
</template>
<script setup>
const items = [
{id: 1, name: 'Apple'},
{id: 2, name: 'Banana'}
];
</script>
父组件接收数据并渲染:
html
<ChildList>
<template #default="slotProps">
<span>{{ slotProps.item.name }} (ID: {{ slotProps.item.id }})</span>
</template>
</ChildList>
或使用解构:
html
<ChildList v-slot="{ item, index }">
<span>{{ index }}: {{ item.name }}</span>
</ChildList>
特点
- 子组件通过
<slot :data="value">
传递数据。 - 父组件通过
v-slot="props"
接收数据,可自由定制渲染逻辑。
插槽对比总结
类型 | 作用 | 语法(父组件) | 子组件示例 |
---|---|---|---|
默认插槽 | 基础内容分发 | <Child>内容</Child> | <slot>默认内容</slot> |
具名插槽 | 多位置定向分发 | <template #header>标题</template> | <slot name="header"></slot> |
作用域插槽 | 子传数据,父决定渲染 | <template #default="{ data }">...</template> | <slot :data="value"></slot> |
高级用法
- 动态插槽名html
<ChildComponent> <template #[dynamicSlotName]> 动态插槽内容 </template> </ChildComponent>
- 插槽作用域样式
- 默认情况下,父组件传入的内容受父组件样式作用域影响。
- 使用
:slotted
选择器(需 Vue 3.3+):
html<style scoped> :slotted(.highlight) { color: red; } </style>
- 渲染作用域
- 插槽内容在父组件作用域编译,无法直接访问子组件数据。
- 子组件数据需通过作用域插槽传递。