本文详细讲解 Vue 插槽(slot)与作用域插槽(scoped slot)的原理与实战用法,通过构建可复用的布局组件,帮助读者掌握组件内容分发与数据传递技巧,...
快速概述
在 Vue 组件化开发中,插槽(slot)是组件内容分发的核心机制,它允许父组件向子组件传递模板内容,从而构建灵活可复用的布局组件。作用域插槽(scoped slot)则进一步让子组件将数据暴露给父组件,实现更精细的内容定制。本文适用于已掌握 Vue 基础(如组件、props、事件)的开发者,环境要求为 Node.js 20.19.0 或更高版本,以及 Vue 3 项目(推荐使用 Vite 构建工具)。
核心概念与原理
插槽的本质是组件模板中的占位符,父组件通过填充内容来定制子组件的渲染结果。具名插槽允许一个组件定义多个插槽,通过 name 属性区分,父组件使用 template v-slot:name 指定填充位置。作用域插槽则通过 v-slot:default="slotProps" 接收子组件传递的数据,实现数据驱动的动态内容。这种设计模式将布局结构与数据逻辑解耦,使组件既保持通用性,又能适应多样化的业务需求。
实战步骤与代码
以下通过构建一个卡片布局组件,演示插槽与作用域插槽的完整用法。
步骤 1:创建项目
使用 Vue 官方脚手架创建项目:
npm create vue@latest
按提示输入项目名,选择 Vue 3 与 TypeScript(可选)
cd my-project npm install npm run dev
步骤 2:定义基础插槽组件
创建 BaseCard.vue,使用默认插槽和具名插槽:
<template>
<div class="card">
<header>
<slot name="header">默认标题</slot>
</header>
<main>
<slot>默认内容</slot>
</main>
<footer>
<slot name="footer">默认底部</slot>
</footer>
</div>
</template>
父组件使用:
<BaseCard>
<template v-slot:header>我的卡片</template>
<p>这是卡片内容</p>
<template v-slot:footer>底部信息</template>
</BaseCard>
步骤 3:实现作用域插槽
创建 UserList.vue,将数据通过作用域插槽暴露给父组件:
<template>
<ul>
<li v-for="user in users" :key="user.id">
<slot :user="user" :index="index">{{ user.name }}</slot>
</li>
</ul>
</template>
<script setup> const users = [ { id: 1, name: '张三', role: '管理员' }, { id: 2, name: '李四', role: '编辑' } ] </script>
父组件定制渲染:
<UserList> <template v-slot:default="slotProps"> <span>{{ slotProps.user.name }} - {{ slotProps.user.role }}</span> </template> </UserList>
步骤 4:组合使用
将插槽组件组合成更复杂的布局,例如带列表的卡片:
<BaseCard>
<template v-slot:header>用户列表</template>
<UserList>
<template v-slot:default="slotProps">
<strong>{{ slotProps.user.name }}</strong>
</template>
</UserList>
</BaseCard>
常见坑点与优化
- 插槽内容不更新:当插槽内容依赖父组件数据时,确保数据是响应式的,否则使用
computed或watch触发更新。 - 作用域插槽解构:在模板中直接解构
slotProps可能报错,建议使用v-slot="{ user }"语法。 - 具名插槽缩写:Vue 3 中
v-slot:header可缩写为#header,但注意默认插槽不能缩写。 - 性能优化:避免在插槽内容中创建复杂计算,可将计算逻辑移至子组件或使用
computed缓存。
通过合理使用插槽,可以显著提升组件的复用性,减少重复代码,使布局组件更加灵活可维护。
评论列表 0