作用域插槽是父组件使用子组件内部数据的插槽类型,核心是子组件通过v-bind绑定数据到slot、父组件用v-slot解构接收并直接使用。

作用域插槽是让父组件能使用子组件内部数据的插槽类型。它不是单纯“放内容”,而是“带数据地放内容”——子组件把变量(比如列表项、索引、状态)通过 <slot></slot> 绑定传出去,父组件在接收时用 v-slot 解构拿到,直接在自己的模板里渲染。
作用域插槽的核心机制
关键就三点:子组件发、父组件收、数据在父作用域可用。
- 子组件在
<slot></slot>标签上用v-bind(或简写:)绑定要传出的数据,例如<slot :item=" currentItem" :index="i"></slot> - 父组件用
v-slot="{ item, index }"或#default="{ item, index }"接收,解构出变量 - 解构后的
item、index就在父组件模板中可直接使用,比如{{ item.name }}或v-if="item.active"
一个完整示例:列表项自定义渲染
假设子组件循环展示用户列表,但想让父组件决定每项怎么显示。
子组件(UserList.vue):
父组件中使用:
{{ isFirst ? '?' : `#${index + 1}` }}
{{ item.name }} ({{ item.age }}岁)
常见写法与注意事项
- 具名作用域插槽写法统一:用
#header="{ title }"替代旧版slot-scope(Vue 2.6+ 已废弃) - 如果只传一个对象,可简写为
v-slot="props",然后用{{ props.item.name }} - 默认插槽可省略
name,但作用域插槽必须显式用#default或v-slot接收,不能直接写在子组件标签内 - 子组件未绑定任何 prop 到
<slot></slot>,父组件就收不到数据——空<slot></slot>只是普通插槽,不是作用域插槽
为什么不能用 ref 或事件代替?
ref 只能拿到整个子组件实例,无法精准获取某次循环中某个 slot 对应的数据;事件需手动触发且耦合重。而作用域插槽是声明式、按需传递、天然响应式的方案,一次定义,自动更新。









