Vue渲染函数中slot选项含义及用法困惑求解
搞懂Vue渲染函数里的slot选项
我来帮你把这个Vue渲染函数中的slot选项逻辑理清楚,你之前的误解其实是搞混了「插槽的定义」和「插槽内容的传递」这两个环节~
先看你代码里的问题
你在render-component的render函数里,给生成的div加了{ slot: 'header' },但父组件通过v-slot:header传的内容没生效,原因是你把「定义组件自己的插槽」和「给其他组件传插槽内容」搞反了。
文档那句话的正确理解
文档说的「当该组件作为另一个组件的子组件时,slot指的是插槽名称」,重点在这个元素是「其他组件的子元素」——也就是说,当你用渲染函数创建一个元素,并且把它作为某个父组件的子元素传递时,这个元素上的slot选项,是用来指定「我要放到父组件的哪个插槽里」。
分两种场景拆解
1. 组件内部定义自己的插槽
如果你的render-component想要提供header和footer插槽给父组件用,不能给普通div加slot选项,而是要在render函数里生成**<slot>节点**,这才是定义组件的插槽:
Vue.component('render-component', { render(h) { return h('div', { class: 'main' }, [ // 这里用h('slot')定义组件的具名插槽 h('slot', { name: 'header' }, '默认header内容'), // 第三个参数是插槽默认值 h('slot', { name: 'footer' }, '默认footer内容') ]) } })
这样父组件里的<template v-slot:header>111111</template>就能正确渲染到render-component的header插槽位置了。
2. 给其他组件传递插槽内容(对应文档描述的场景)
当你在父组件的render函数里,给render-component传递子元素时,这时候给子元素加slot选项,就是指定这个内容要放到render-component的哪个插槽里,这就是文档说的情况:
let vm = new Vue({ el: '#app', render(h) { return h('render-component', {}, [ // 这个div是render-component的子元素,slot选项指定它要放到header插槽 h('div', { slot: 'header' }, '父组件通过渲染函数传的header内容'), h('div', { slot: 'footer' }, '父组件通过渲染函数传的footer内容') ]) } })
这时候这个div作为render-component的子组件(子元素),它的slot选项就对应了目标组件的插槽名称。
总结一下
- 定义组件的插槽:用
<slot name="xxx">(模板写法)或者h('slot', { name: 'xxx' })(渲染函数写法) - 给组件传插槽内容:在父组件中,要么用模板的
v-slot:xxx,要么在渲染函数里给子元素加{ slot: 'xxx' }——这时候文档的描述就完全对应上了。
内容的提问来源于stack exchange,提问作者ChenLee




