本文系统讲解 Vue 插槽(Slot)的核心机制,从默认插槽、具名插槽到作用域插槽,结合可复现的代码示例与常见坑点,帮助开发者构建灵活、可复用的组件。...
快速概述
Vue 插槽(Slot)是组件内容分发机制,解决的是组件复用与内容定制之间的冲突。当多个页面需要共用同一套布局或逻辑,但内部细节不同时,插槽允许父组件向子组件注入自定义内容。适用场景包括:弹窗组件、卡片布局、表格列定制、导航栏等。前置环境要求:Vue 2.6+ 或 Vue 3.x,且熟悉组件基础语法。
核心概念与原理
插槽的本质是作用域隔离的内容占位符。子组件通过 <slot> 标签声明一个渲染位置,父组件在引用子组件时,将模板内容填充到该位置。Vue 在编译阶段将插槽内容编译为渲染函数,并在子组件渲染时执行,从而实现内容分发。根据需求,插槽分为三种:默认插槽(匿名)、具名插槽(通过 name 属性区分)和作用域插槽(子组件向父组件传递数据)。
实战步骤与代码
1. 创建基础组件
创建一个 Card 组件,使用默认插槽接收内容:
<!-- Card.vue -->
<template>
<div class="card">
<div class="card-header">卡片标题</div>
<div class="card-body">
<slot></slot> <!-- 默认插槽,父组件内容将渲染在此 -->
</div>
</div>
</template>
2. 使用默认插槽
<template>
<Card>
<p>这是插入到卡片中的自定义内容</p>
</Card>
</template>
3. 具名插槽
当组件有多个插槽时,使用 name 属性区分:
<!-- Card.vue 扩展 -->
<slot name="header">默认头部</slot>
<slot name="footer">默认底部</slot>
<!-- 父组件使用 --> <Card> <template #header> <h2>自定义头部</h2> </template> <template #footer> <button>确定</button> </template> </Card>
4. 作用域插槽
子组件向父组件传递数据,实现反向通信:
<!-- ListItem.vue -->
<template>
<li>
<slot :item="item" :index="index">{{ item }}</slot>
</li>
</template>
<script setup>
defineProps({ item: String, index: Number })
</script>
<!-- 父组件使用 --> <ListItem v-for="(item, i) in items" :item="item" :index="i"> <template #default="{ item, index }"> <span>{{ index + 1 }}. {{ item }}</span> </template> </ListItem>
常见坑点与优化
- 插槽内容无法访问子组件数据:默认插槽内容在父组件作用域编译,如需子组件数据必须使用作用域插槽。
- 具名插槽简写冲突:
#default与v-slot:default等价,但注意#后不能有空格。 - 动态插槽名:Vue 3 支持
<template v-slot:[dynamicName]>,但动态名需为合法字符串。 - 性能优化:避免在插槽内容中创建大型计算属性或复杂表达式,插槽内容会随父组件更新而重新渲染;可使用
v-memo或拆分组件减少渲染开销。 - 作用域插槽解构:使用解构时注意默认值语法
#default="{ item = '默认值' }",避免 undefined 报错。
掌握插槽机制后,组件复用性将显著提升。建议在项目中优先使用作用域插槽实现数据驱动的内容定制,并保持插槽命名语义化。
评论列表 0