全部学科
Python全栈
python
NodeJS全栈
nodejs
小程序首页
📅 2026-05-20 8 分钟 ✍️ juanwangdev

插槽实现原理

插槽本质是特殊的prop传递,Vue通过 $slots$scopedSlots 实现内容分发与作用域数据绑定。

插槽编译过程

JavaScript
// 模板: <slot name="header" :data="msg"/>
// 编译为渲染函数
function render() {
  return this.$scopedSlots.header({ data: this.msg })
}

具名插槽和作用域插槽最终都编译为 $scopedSlots 的函数调用。

$slots 与 $scopedSlots

JavaScript
// 普通插槽: <slot/>
vm.$slots = {
  default: [VNode, VNode]  // 预渲染的VNode数组
}

// 作用域插槽: <slot :data="msg"/>
vm.$scopedSlots = {
  default: function(props) {
    // 返回VNode的函数,props由父组件传入
  }
}

普通插槽是预渲染的VNode数组,作用域插槽是返回VNode的函数。

父组件传递插槽内容

JavaScript
// 父组件
createElement(Child, {}, [
  createElement('div', '默认内容')
])

// 等价于
h(Child, {}, {
  default: () => h('div', '默认内容')
})

父组件通过第三个参数或slots选项传递插槽内容。

子组件渲染插槽

JavaScript
// 子组件内部
Vue.component('Child', {
  render(h) {
    return h('div', [
      this.$slots.default,        // 普通插槽
      this.$scopedSlots.header?.({ msg: 'hello' })  // 作用域插槽
    ])
  }
})

子组件通过访问 $slots$scopedSlots 渲染传入内容。

作用域插槽数据流

JavaScript
// 子组件定义
{
  props: ['items'],
  render(h) {
    return h('ul', [
      this.$scopedSlots.default({
        items: this.items,  // 将数据传给父组件
        index: 0
      })
    ])
  }
}

// 父组件使用
<Child :items="list" v-slot="{ items, index }">
  <li>{{ items[index] }}</li>
</Child>

子组件将数据作为参数传入插槽函数,父组件通过解构接收。

插槽VNode生成

JavaScript
function normalizeSlot(name, props, scopedSlots) {
  const slotFn = scopedSlots[name]
  if (slotFn) {
    return slotFn(props)  // 执行函数获取VNode
  }
  return null
}

作用域插槽通过执行函数并传入子组件数据获取VNode。

要点总结

  • 插槽本质是prop传递,普通插槽是VNode数组,作用域插槽是函数
  • $slots 存储预渲染VNode,$scopedSlots 存储返回VNode的函数
  • 父组件传递插槽内容,子组件通过 $slots/$scopedSlots 访问
  • 作用域插槽实现子组件向父组件传递数据
  • 插槽编译后统一为 $scopedSlots 函数调用

📝 发现内容有误?点击此处直接编辑

← 上一篇 全局API实现
下一篇 → 插值表达式与事件绑定
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库