1

我正在尝试制作一个功能组件,该组件根据道具呈现一个组件或另一个组件。其中一个输出必须是一个<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,
    attrs: context.data.attrs,
    on: context.listeners,
    scopedSlots: {
      loading(props) {
        // Never called because no props it passed to that slot
        return context.slots()['loading']
      }
    }
  },

有没有办法将插槽传递给我正在渲染的组件而不添加包装元素?

4

1 回答 1

1

我发现使用该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'])
    ],
  )
}
于 2021-07-06T12:33:00.670 回答