Vue:如何将类/样式添加到无渲染组件插槽?

时间:2020-07-29 09:44:09

标签: vue.js

是否可以将类和样式添加到无渲染组件的子插槽中?

感谢您的帮助,因为我为此付出了很多时间,但到目前为止没有成功。

我有一个不渲染的组件(请注意,我正在使用Composition API,但该问题也与Options API有关)

export default {
  name: 'Renderless',
  setup (_, { slots }) {
    return () => slots.default()[0]
  }
}

我想这样使用:

<renderless>
  <some-other-component />
</renderless>

此外,我希望Renderless组件能够向子插槽添加类和样式,具体取决于Renderless组件中的某些条件,例如道具值更改或鼠标悬停在其上,等等。

一个重要的要求是Renderless组件添加自己的标签,例如这不是我想要的:

setup (_, { slots }) {
  return () => h('div', {...}, slots.default()[0])
}

我尝试过的

  1. 直接修改默认插槽VNode
setup (_, { slots }) {
  const someVar = ref(false)
  return () => slots.default().map(vNode => {
    vNode.data.class = { 'some-class': someVar.value }
  })[0]
}

但这不适用于ref,它仅在我使用{ 'some-class': true }而不是我需要的情况下才有效。

  1. 提取要与h()函数一起使用的VNode属性:
setup (_, { slots }) {
  const someVar = ref(false)
  const defaultSlot = slots.default()[0]
  return () => h(
    defaultSlot.tag,
    {
      ...defaultSlot.data,
      class: { 'some-class': someVar.value }
    },
    defaultSlot.children
  )
}

但这仅在插槽包含HTML元素时才有效-当插槽是组件时,我无法使其正常工作。

  1. 使用范围限定的道具传递给父级:
setup (_, { slots }) {
  const someVar = ref(false)
  return () => slots.default({ classes: { 'some-class': someVar.value } })[0]
}

,然后在父项中:

<renderless v-slot="props">
  <some-other-component :class="props.classes" />
</renderless>

但是我不喜欢这样,因为如果强迫父母明确地绑定class道具,以便在子组件上设置类,我想在幕后进行而不是承担上级组件的责任。

我知道在上述设置中使用术语“无渲染”可能并不完全正确,因为我希望组件将一些CSS渲染到其子元素中,但是尽管有适当的命名,这也是我想要实现的目标:slight_smile :

0 个答案:

没有答案