vue插槽本质是编译期约定与运行时函数调用:父组件将插槽内容编译为返回vnode的函数挂载到$slots,子组件渲染时调用该函数并传入作用域参数,实现内容复用与响应式更新。

Vue.js 编译器处理插槽时,数据流向是单向且分阶段的:父组件决定“传什么内容”,子组件决定“在哪接收、怎么暴露”,而作用域插槽额外增加了一条“子→父”的数据回传路径。
父组件模板编译:内容被封装为函数
父组件中写的插槽内容(比如 <template>{{ item.name }}</template>)不会直接渲染,而是被 Vue 编译器转换成一个**返回 VNode 的函数**,并挂载到子组件实例的 $slots 对象上。这个函数本身不执行,只保存结构和绑定关系。
- 默认插槽 → 存入
$slots.default - 具名插槽(如
v-slot:header)→ 存入$slots.header - 作用域插槽 → 函数参数由子组件提供,但函数体仍在父作用域内定义
子组件渲染阶段:调用插槽函数并注入作用域
子组件执行自己的 render 函数时,遇到 <slot></slot> 标签,就会调用对应 $slots.xxx(),并将当前子组件实例的数据作为参数传入(仅限作用域插槽)。例如:
$slots.default({ user: ..., index: ... })
- 普通插槽:调用时无参数,纯内容复用
- 作用域插槽:参数对象在子组件响应式上下文中求值,保证
user.name是响应式的 - 插槽函数执行环境仍是父组件作用域,所以
{{ user.name }}中的user来自子组件,但解析逻辑在父组件编译生成的函数里
虚拟 DOM 更新:插槽内容随依赖自动重计算
插槽内容是否更新,取决于两个层面:
- 父组件插槽函数内部引用的响应式变量变化 → 触发该函数重新执行,生成新 VNode
- 子组件传递的作用域数据变化(如
currentUser被修改)→ 同样触发插槽函数重执行 - Vue 通过依赖收集机制跟踪这两类依赖,确保插槽内容精准响应
关键结论:不是“数据流”,而是“函数调用 + 作用域桥接”
插槽本质不是传统意义上的数据流管道,而是一种**编译期约定 + 运行时函数调用**机制:
- 父组件提供模板函数,子组件负责调用时机和传参
- 作用域插槽的“数据回传”其实是子组件把自身状态作为参数,交由父组件模板函数消费
- 所有插槽内容最终都属于父组件的虚拟 DOM 树,只是渲染位置嵌套在子组件结构中
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











