作用域插槽实现子传父响应式数据传递:子组件通过v-bind在slot上显式暴露字段,父组件用v-slot解构接收,保持单向数据流且响应式更新。

父组件不能直接访问子组件内部的响应式数据,但可以通过作用域插槽“接收”子组件主动暴露的数据。核心不是“获取”,而是“子传父”的声明式响应式传递——子组件决定传什么、怎么传,父组件按名解构使用。
子组件:在 slot 标签上绑定要传出的数据
必须用 v-bind(或简写 :)把响应式字段显式挂到 <slot></slot> 上,不能传 this 或整个实例。
- 传单个对象:
<slot :user="currentUser"></slot> - 传多个字段:
<slot :item="item" :index="i" :is-active="item.active"></slot> - 配合列表循环:
<slot v-for="item in list" :key="item.id" :row="item"></slot>
父组件:用 v-slot 解构接收并直接使用
必须用 v-slot(或简写 #default)显式接收,不能省略;解构名可自定义,但需与子组件绑定的属性名一致。
递归分析 Vue 项目组件依赖,从入口文件生成组件层级图,支持 Vue 2/3,输出组件名、文件路径和属性。适用于分析组件结构、排查依赖或了解项目架构。
- 默认插槽:
<mylist v-slot="{ user, index }">{{ user.name }} - {{ index }}</mylist> - 命名插槽更清晰:
<mytable v-slot:body="{ row }"><td>{{ row.title }}</td></mytable> - 事件中也能直接用:
<mylist v-slot="{ item }"><button>编辑</button></mylist>
关键细节:响应式与边界
只要子组件传的是 ref 或 reactive 对象,父组件解构出的字段就保持响应式更新;但父组件不能反向修改这些字段——这是单向数据流设计。
- ✅ 子组件改
currentUser.name→ 父组件{{ user.name }}自动刷新 - ❌ 父组件写
user.name = 'Bob'→ 不影响子组件状态 - ⚠️ 避免传整个
data或props对象,只暴露必要字段,利于解耦
常见误区与替代思路
插槽内容默认在父组件作用域编译,所以父模板里写 {{ title }} 是拿不到子组件 props 的——这不是 bug,是机制。
- ❌ 错误:子组件写
<slot>{{ title }}</slot>,指望父组件直接渲染 - ✅ 正确:子组件写
<slot :title="title"></slot>,父组件用v-slot="{ title }" - 若需双向控制(如父改子数据),优先用
v-model或props + emit,而非强行用作用域插槽










