作用域插槽核心是子组件向父组件传递渲染上下文而非节点,通过<slot v-bind="obj">暴露数据,父组件用v-slot="{ prop }"解构接收,参数仅在子组件渲染时有效且非响应式代理。

作用域插槽的核心是“子传父”——子组件把数据通过插槽暴露给父组件,父组件用 v-slot(或简写 #)接收并使用这些数据。关键不在“传递节点”,而在“传递上下文”,且这个上下文只在渲染时生效。
子组件定义带参数的插槽
在子组件模板中,用 <slot> 的 v-bind 绑定任意响应式数据(对象、数组、函数、ref 等),这些就是将传给父组件的“插槽参数”:
<slot :user="currentUser" :index="idx" :isActive="true"></slot>- 多个属性可合并为一个对象:
<slot v-bind="{ user: currentUser, index: idx }"></slot> - 支持解构后的响应式值,比如
toRefs处理过的属性也能正常传递
父组件用 v-slot 解构接收
父组件必须用 <template v-slot:xxx="slotProps"> 或简写 <template #xxx="slotProps"> 包裹内容,slotProps 是一个包含所有绑定属性的对象:
- 默认插槽写法:
<template #default="{ user, index, isActive }">{{ user.name }} — {{ index }}</template> - 具名插槽写法:
<template #item="{ user, index }"><UserCard :user="user" /></template> - 也可不结构直接用:
<template #default="props">{{ props.user.name }}</template>
注意插槽参数的运行时特性
插槽本质是函数,参数只在子组件渲染时执行并返回 VNode,所以:
立即学习“前端免费学习笔记(深入)”;
- 父组件里不能在
setup中提前读取slotProps,它只存在于模板作用域 - 若子组件未渲染该插槽(比如条件不满足),对应
slots.xxx就是undefined,调用前需判空(如slots.item?.({ user })) - 插槽参数不是响应式代理,但若传的是 ref 或 reactive 对象,其内部变化仍可被父组件模板响应
常见误点提醒
容易混淆的几个事实:
- 插槽内容本身运行在父组件作用域,所以能访问父组件的
data、ref、computed,但不能直接访问子组件的数据 -
v-slot只能用在<template>标签上(或直接写在组件标签内作为隐式默认插槽),不能写在普通 HTML 标签上 - 不要试图在父组件中修改传入的插槽参数——那是子组件控制的上下文,父组件只负责消费


















