Vue 渲染功能:在没有包装器的情况下为子组件包含插槽

问题描述

我正在尝试制作一个功能组件,该组件根据道具呈现一个或另一个组件。 输出之一必须是一个 <v-select> 组件,我想将它传递给它的所有插槽/道具,就像我们直接调用它一样。

<custom-component :loading="loading">
  <template #loading>
    <span>Loading...</span>
  </template>
</custom-component>

<!-- Should renders like this (sometimes) -->
<v-select :loading="loading">
  <template #loading>
    <span>Loading...</span>
  </template>
</v-select>

但是我无法找到一种方法来将提供给我的功能组件的插槽包含到我正在渲染的内容中,而无需在它们周围添加包装器:

render (h: CreateElement,context: RenderContext) {
  // Removed some logic here for clarity
  return h(
    'v-select',{
      props: context.props,attrs: context.data.attrs,on: context.listeners,},[
      // I use the `slot` option to tell in which slot I want to render this.
      // But it forces me to add a div wrapper...
      h('div',{ slot: 'loading' },context.slots()['loading'])
    ],)
}

我不能使用 scopedSlots 选项,因为这个插槽(例如)没有插槽道具,所以永远不会调用函数

return h(
  'v-select',{
    props: context.props,scopedSlots: {
      loading(props) {
        // Never called because no props it passed to that slot
        return context.slots()['loading']
      }
    }
  },

有没有什么方法可以将插槽传递给我正在渲染的组件,而无需向它们添加包装元素?

解决方法

我发现使用 createElement 函数来呈现 <template> 标签是完全有效的,这与用于确定我们在哪个插槽上的标签相同。

所以像这样使用它可以解决我的问题:

render (h: CreateElement,context: RenderContext) {
  // Removed some logic here for clarity
  return h(
    'v-select',{
      props: context.props,attrs: context.data.attrs,on: context.listeners,},[
      // I use the `slot` option to tell in which slot I want to render this.
      // <template> vue pseudo element that won't be actually rendered in the end.
      h('template',{ slot: 'loading' },context.slots()['loading'])
    ],)
}