作用域插槽是子组件将内部响应式数据通过绑定暴露给父组件,父组件用v-slot解构接收并直接使用,实现单向(子→父)响应式数据传递。

作用域插槽就是子组件把内部数据“打包”传给父组件插槽,让父组件能在自己的模板里直接使用这些数据。它不是简单地放内容,而是带数据地放内容——关键在“传出去”和“收得准”。
子组件怎么把数据传出来
在子组件的<slot></slot>标签上,用v-bind(或简写:)绑定要暴露的变量。这些变量必须是子组件内定义的响应式数据(比如ref、reactive对象里的字段),不能直接传this或整个实例。
- 传单个字段:
<slot :user="currentUser"></slot> - 传多个字段:
<slot :item="item" :index="i" :is-active="item.active"></slot> - 配合
v-for传列表项:<slot v-for="item in list" :key="item.id" :row="item"></slot>
父组件怎么把数据收进来
父组件用v-slot(或简写#default)接收,并通过解构语法拿到变量。解构名可以自定义,但必须和子组件绑定的属性名对应。
- 默认插槽写法:
<mylist v-slot="{ user, index }">{{ user.name }} - {{ index }}</mylist> - 命名插槽更清晰:
<mytable v-slot:body="{ row }"><td>{{ row.title }}</td></mytable> - 支持嵌套使用:
v-slot="{ row }" @click="handleEdit(row)",事件回调里也能直接用子组件数据
为什么它能响应式更新
只要子组件传的是响应式对象(比如ref({ name: 'Alice' })或reactive({ count: 0 })),父组件中解构出来的字段就保持响应式。修改子组件数据,父组件插槽内容会自动刷新;反过来,父组件不能直接改这些字段——作用域插槽只支持单向传递(子→父)。
- ✅ 正确:子组件更新
currentUser.name,父组件{{ user.name }}实时变化 - ❌ 错误:在父组件里写
user.name = 'Bob',不会影响子组件状态 - ⚠️ 注意:如果需要双向操作,应改用
v-model或props + emit组合
实际用在哪几类场景
适合子组件管逻辑、父组件管渲染的分工模式:
- 自定义列表项:表格每行结构由父组件决定,数据和分页逻辑由子组件管理
- 弹窗/卡片容器:子组件控制显隐和动画,父组件注入标题、按钮、内容块
- 表单控件封装:子组件处理校验和输入行为,父组件定制提示文案或错误样式

















