Vue 3 子组件传递 slot 样式

8

摘要:我需要样式化一个子组件中的<slot>内容。我正在使用作用域 CSS,但样式不被应用:

我有以下两个组件:

<!-- Parent.vue -->
<template>
  <h1>{{ msg }} from Parent</h1>
  <Child>
    <h1>{{ msg }} from Child</h1>
  </Child>
</template>
...
<style scoped>
h1 {
  color: green;
}
</style>


<!-- Child.vue -->
<template>
  <slot></slot>
</template>
...
<style scoped>
h1 {
  color: red;
}
</style>

我想让第二个<h1>变成红色,但它是绿色的,因为该组件被呈现为类似于:

<h1 data-v-452d6c4c data-v-2dcc19c8-s>Hello from Child</h1>

<style>
h1[data-v-452d6c4c] {
  color: green;
}
h1[data-v-2dcc19c8] {
  color: red;
}
</style>

data-v-452d6c4c来自父组件,data-v-2dcc19c8-s来自子组件。

如果在<h1>标签的第二个属性只是data-v-2dcc19c8,那么我想要的样式就会应用,但由于它带有-s后缀(插槽?),所以不会应用。

我可能可以找到其他的解决方案,比如使用类之类的东西,但我很少使用<slot>,我想了解其中的内部工作原理。那个-s告诉我,我尝试做的事情可以通过框架的帮助来处理,我错过了什么吗?

一个可工作的示例:

https://codesandbox.io/s/condescending-brown-ilfwn

1个回答

21

在Vue 3中使用新的:slotted选择器:https://v3.vuejs.org/api/sfc-style.html#slotted-selectors

Child.vue

<template>
  <slot></slot>
</template>

<script>
export default {
  name: "Child",
};
</script>

<style scoped>
:slotted(h1) {
  color: red !important;
}
</style>
在Vue 3中,默认情况下,子级scoped样式不会影响分发内容。 在您的特定示例中,!important修饰符也是必需的,因为父级还定义了一个h1样式,否则将优先使用该样式。

1
谢谢您的回答,我已经寻找了相当长时间的Vue插槽样式方法。 - Marcos de Andrade
文档中有关于这个的页面吗?搜索 v-slotted 没有显示任何结果。 - Mike Harrison
3
@MikeHarrison - 在这里:https://v3.vuejs.org/api/sfc-style.html#slotted-selectors,实际上语法已经更改。现在您可以使用`:slotted(h1)`而不是`::v-slotted(h1)`。答案已经被更新以反映这一点。(重新发布评论以修复链接。) - Dan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接