作用域插槽允许子组件向父组件传递数据,通过slot属性传入响应式对象,父组件用v-slot解构接收;支持默认插槽、命名插槽及配合v-for动态渲染,但仅适用于单向数据流,双向通信应使用v-model或props+emit。

父组件不能直接访问子组件的数据,但通过作用域插槽(Scoped Slots),可以将子组件内部的数据“暴露”给父组件使用,实现反向数据传递。本质是子组件在渲染插槽时,把自身数据作为插槽参数传出去,父组件在使用插槽时接收并使用这些参数。
作用域插槽的基本写法
子组件中用 v-slot:xxx="scope"(或简写 #xxx="scope")接收插槽内容,并通过
- 子组件模板中:<slot :user="userInfo" :loading="isLoading"></slot>
- 父组件使用时:<MyComponent v-slot="{ user, loading }">{{ user.name }} 加载中:{{ loading }}</MyComponent>
命名插槽 + 作用域参数更清晰
当有多个插槽或需要语义化时,推荐用命名作用域插槽:
- 子组件:<slot name="header" :title="pageTitle"></slot>
- 父组件:<MyComponent v-slot:header="{ title }"><h2>{{ title }}</h2></MyComponent>
这样既复用插槽结构,又让父组件精准拿到所需数据,避免命名冲突。
立即学习“前端免费学习笔记(深入)”;
结合 v-for 和作用域插槽动态渲染
常见于列表类子组件(如 Table、List),子组件管理数据和状态,父组件只负责渲染逻辑:
- 子组件中循环时把每一项数据传给插槽:<slot v-for="item in list" :key="item.id" :row="item"></slot>
- 父组件可自定义每行内容:<MyTable v-slot="{ row }"><td>{{ row.name }}</td><td><button @click="edit(row)">编辑</button></td></MyTable>
注意点与替代方案
- 作用域插槽是单向的(子→父),不触发响应式更新?错——只要传的是响应式对象(如 ref 或 reactive),父组件中使用仍响应式
- 避免直接传整个 this 或子组件实例,应只暴露必要字段,保持解耦
- 若需双向通信(如父组件修改子组件数据),优先考虑 v-model 或 props + emit,作用域插槽不是为双向设计的










