Vue 中插槽 slot 和作用域插槽怎么用? Vue 中插槽 slot 和作用域插槽怎么用一句话总结插槽就是「组件预留一个口让父组件填内容」默认插槽填普通内容具名插槽填多区域作用域插槽让子组件把数据传给父组件决定怎么渲染。本质就是组件内容分发的三件套正文目录三种插槽的核心概念5 大高频场景 代码示例万能兜底插槽使用决策表预防 checklist不再踩坑一句话总结一、三种插槽的核心概念默认插槽父组件往子组件里塞内容!-- 子组件 Card.vue -- template div classcard slot / !-- 父组件的内容会填到这里 -- /div /template !-- 父组件 -- Card p这段内容会渲染到 Card 的 slot 里/p /Card具名插槽预留多个口父组件分别填!-- 子组件 Layout.vue -- template headerslot nameheader //header mainslot //main !-- 默认插槽 -- footerslot namefooter //footer /template !-- 父组件 -- template #header顶部/template template #default中间/template template #footer底部/template作用域插槽子组件把数据传给父组件!-- 子组件 List.vue -- template ul li v-foritem in items :keyitem.id slot :itemitem :indexindex / !-- 把 item 传给父组件 -- /li /ul /template !-- 父组件 -- List :itemsusers template #default{ item, index } span{{ index }}: {{ item.name }}/span /template /List类型数据流向适用场景默认插槽父 → 子塞内容简单内容包裹具名插槽父 → 子多区域卡片/布局多区域作用域插槽子 → 父传数据列表/表格自定义渲染二、5 大高频场景 代码示例① 卡片组件用默认插槽但没写 fallback!-- ❌ 父组件没传内容时卡片中间是空的 -- !-- Card.vue -- template div classcard slot / !-- ❌ 没传内容就是空白 -- /div /template !-- 使用 -- Card/Card !-- ❌ 渲染出一个空卡片 --修复给默认值fallback content!-- ✅ 插槽给默认内容 -- !-- Card.vue -- template div classcard slot p暂无内容/p !-- ✅ 父组件没传时显示默认内容 -- /slot /div /template② 具名插槽用旧语法slot 属性而非新语法# 简写!-- ❌ Vue 2 旧语法Vue 3 中废弃 -- template Layout div slotheader标题/div !-- ❌ slot 属性已废弃 -- div slotfooter底部/div /Layout /template修复用#name或v-slot:name简写!-- ✅ Vue 3 推荐用 # 简写 -- template Layout template #header标题/template !-- ✅ # 简写 -- template #footer底部/template /Layout /template③ 作用域插槽不会接收子组件数据!-- ❌ 父组件想自定义列表渲染但拿不到子组件的 item -- !-- List.vue -- template ul li v-foritem in items :keyitem.id slot / !-- ❌ 没传 item父组件拿不到 -- /li /ul /template !-- 父组件 -- List :itemsusers span{{ item.name }}/span !-- ❌ item 未定义 -- /List修复子组件传数据父组件用解构接收!-- ✅ 子组件把 item 和 index 传给 slot -- !-- List.vue -- script setup defineProps([items]); /script template ul li v-for(item, index) in items :keyitem.id slot :itemitem :indexindex / !-- ✅ 传数据出去 -- /li /ul /template!-- ✅ 父组件解构接收 -- List :itemsusers template #default{ item, index } span{{ index 1 }}: {{ item.name }}/span !-- ✅ 拿到 item -- /template /List④ 列表组件作用域插槽只渲染默认样式!-- ❌ 列表组件写死了渲染方式父组件无法自定义 -- !-- TableList.vue -- template table tbody tr v-forrow in data :keyrow.id td{{ row.name }}/td !-- ❌ 写死了列 -- td{{ row.age }}/td td{{ row.city }}/td /tr /tbody /table /template !-- 使用方想加一列「操作」按钮 → 改不了 ❌ --修复用作用域插槽让父组件决定渲染什么!-- ✅ 用作用域插槽每列由父组件定义 -- !-- TableList.vue -- template table tbody tr v-forrow in data :keyrow.id slot :rowrow !-- ✅ 把整行数据传出去 -- td{{ row.name }}/td !-- 默认渲染 -- td{{ row.age }}/td /slot /tr /tbody /table /template!-- ✅ 父组件自定义每行渲染 -- TableList :datausers template #default{ row } td{{ row.name }}/td td{{ row.age }}/td td button clickedit(row)编辑/button !-- ✅ 自定义列 -- button clickdelete(row)删除/button /td /template /TableList⑤ 动态插槽名根据条件渲染不同插槽!-- ❌ 硬编码插槽名条件多时代码冗长 -- template Layout template v-iftype header #header.../template template v-else-iftype footer #footer.../template /Layout /template修复用动态插槽名!-- ✅ 动态插槽名 -- template Layout template #[slotName] 动态内容 /template /Layout /template script setup import { ref } from vue; const slotName ref(header); // ✅ 动态切换插槽 /script三、万能兜底插槽使用决策表需求用什么示例包裹一段内容默认插槽Cardp内容/p/Card多区域填充具名插槽#header#footer子组件传数据给父组件作用域插槽:itemitem#default{ item }没传内容时显示默认fallbackslot默认值/slot条件渲染不同插槽动态插槽名#[slotName]万能模板通用列表组件!-- GenericList.vue -- script setup defineProps({ items: { type: Array, default: () [] }, }); /script template ul li v-for(item, index) in items :keyitem.id ?? index slot :itemitem :indexindex :firstindex 0 !-- ✅ 默认渲染 -- {{ item.name ?? item }} /slot /li /ul /template!-- 使用方1默认渲染 -- GenericList :items[苹果, 香蕉, 橘子] / !-- 使用方2自定义渲染 -- GenericList :itemsusers template #default{ item, index, first } div :class{ highlighted: first } {{ index 1 }}. {{ item.name }} ({{ item.age }}岁) /div /template /GenericList !-- 使用方3具名 作用域 -- Layout template #header{ title } h1{{ title }}/h1 /template template #default p主体内容/p /template /Layout四、预防 checklistVue 3 用#name简写不要用 Vue 2 的slotname属性默认插槽写fallback contentslot默认显示/slot作用域插槽在子组件用:propvalue传数据父组件用#default{ prop }解构列表/表格组件用作用域插槽让父组件自定义渲染动态插槽名用#[variable]语法作用域插槽解构时可以重命名#default{ item: row }→ 用row插槽可以有默认值slot nameheaderh1默认标题/h1/slotv-slot只能用在template标签上#简写也一样五、一句话总结「插槽 组件内容分发的口子」。默认插槽塞内容具名插槽分区域作用域插槽让子组件传数据给父组件渲染。列表/表格组件用作用域插槽实现「数据在子组件渲染由父组件定」灵活度拉满最后问候亲爱的朋友们并邀请你们阅读我的全新著作 《Vue.js 3企业级项目开发实战微课视频版》