css 在< slot>Vue 3中使用作用域样式时,样式无法在内容中正确应用

0x6upsns  于 2023-03-05  发布在  其他
关注(0)|答案(2)|浏览(257)

我正在使用Oruga和Storybook库在Vue 3中制作组件。
Vue文件代码编写为:

<template>
  <o-radio v-bind="$props" v-model="model">
    <slot />
  </o-radio>
</template>

<script lang="ts">
import { defineComponent } from "@vue/runtime-core";
import Radio from '../mixins/radio-mixins';

export default defineComponent({
  name: "BaseRadio",
  computed: {
    model: {
      get() {
        return this.$props.nativeValue;
      },
      set(value: any) {
        this.$emit("input", value);
      },
    },
  },
  emits: ["input"],
  props: {
    ...Radio.props,
  },
});
</script>

<style scoped>
  .b-radio.radio.is-primary .check:checked {
    border-color: var(--color-blue);
  }
  .b-radio.radio.is-primary .check:checked:focus {
    box-shadow: 0 0 3px 3px var(--color-light-blue);
  }
  .b-radio.radio.is-primary .check:before {
    background: var(--color-blue);
  }
</style>

<style>标记中,我修改了Oruga库提供的元素类,以实现所需的样式。
主要的问题是当我在<style>标签上使用scoped时,我的样式没有一个被应用到渲染视图中,省略scoped可以使它再次工作。
如何解决这个问题?我需要在应用这些样式的同时使用<style>中的scoped标签。

abithluo

abithluo1#

可能是因为您正在尝试更改只存在于DOM本身的类,因为您正在使用Oruga,所以当您省略“scoped”属性时,您能够全局操作oruga类。

mspsb9vt

mspsb9vt2#

默认情况下,slotted内容(通过<slot>标记呈现的元素)不受<slot>所在组件的作用域样式的影响,相反,该内容被视为由其 parent(实际上呈现到<slot>中的组件)“拥有”。
这给您留下了3个选项:

将样式直接放入开槽组件中

如果您将呈现的组件中的样式放入槽中,则无论组件在何处呈现,样式都将应用于该组件。
然而,如果你不控制插槽组件,这并不总是理想的,甚至是不可能的。

使用:slotted()属性

::slotted() pseudo-attribute是专门设计来引用<slot>标签中呈现的元素的。Vue 3有自己的:slotted()版本(注意单个冒号:而不是两个::)。

<style scoped>
  :slotted(.b-radio.radio.is-primary .check:checked) {
    border-color: var(--color-blue);
  }
  :slotted(.b-radio.radio.is-primary .check:checked:focus) {
    box-shadow: 0 0 3px 3px var(--color-light-blue);
  }
  :slotted(.b-radio.radio.is-primary .check:before) {
    background: var(--color-blue);
  }
</style>

使用:deep()属性

scoped属性明确地将样式限制到它们声明的组件,但是:deep()选择器允许组件将样式应用到其子组件,包括开槽组件,因为它们在DOM中呈现为子节点。

<style scoped>
  :deep(.b-radio.radio.is-primary .check:checked) {
    border-color: var(--color-blue);
  }
  :deep(.b-radio.radio.is-primary .check:checked:focus) {
    box-shadow: 0 0 3px 3px var(--color-light-blue);
  }
  :deep(.b-radio.radio.is-primary .check:before) {
    background: var(--color-blue);
  }
</style>

然而,请注意,这样做会进一步污染样式链中的样式范围;sugrands节点和其他节点仍然会受到这些样式的影响。如果你不小心使用类名和选择器,这可能会导致问题。

相关问题