具有嵌套 scss 规则的 :deep() 语法

sja*_*rni 6 sass vue.js vue-sfc dart-sass

我正在尝试将一些 Vue.js 单文件组件从::v-deep语法迁移到:deep(),如此处所述。但是,我不确定如何使其与嵌套SCSS 规则一起使用&__*。没有工作的规则&__*也很好。

我们使用的 SCSS 编译器是dart-sass

例子

例如,有这个原始片段:

::v-deep .wrapper {
    display: flex;

    &__element {
        display: block
    }
}
Run Code Online (Sandbox Code Playgroud)

正确地将代码编译为

[data-v-S0m3Ha5h] .wrapper__element {
    display: block;
}
Run Code Online (Sandbox Code Playgroud)

并抛出警告:[@vue/compiler-sfc] ::v-deep usage as a combinator has been deprecated. Use :deep(<inner-selector>) instead.

:deep()在顶层规则中

我尝试将其转换为:deep()这样:

:deep(.wrapper) {
    display: flex;

    &__element {
        display: block
    }
}
Run Code Online (Sandbox Code Playgroud)

这会导致编译器错误,因为:deep(wrapper)__element不是有效的选择器

:deep()在嵌套规则中

所以我将 移至:deep嵌套规则:

.wrapper {
    display: flex;

    :deep(&__element) {
        display: block
    }
}
Run Code Online (Sandbox Code Playgroud)

编译没有错误,但产生了拙劣的 css:

.wrapper[data-v-S0m3Ha5h] &__element {/* ... */}
Run Code Online (Sandbox Code Playgroud)

问题

如何使用嵌套&__*规则:deep()

ton*_*y19 3

:deep由于您提到的原因,Sass 显然不允许嵌套(或任何其他伪类)的选择器参数列表,但有一些解决方法。

解决方法 1:拆分 Sass 样式

拆分样式,以便:deep选择器列表不嵌套:

<!-- MyParent.vue -->
<style scoped lang="scss">
:deep(.wrapper) {
    display: flex;
}
:deep(.wrapper__element) {
    display: block;
}
</style>
Run Code Online (Sandbox Code Playgroud)

演示1

解决方法 2:拆分类名称

分解 BEM 类名(从wrapper__element__element),以便不需要父选择器:

<!-- MyComponent.vue -->
<template>
    <div class="wrapper">
        <div class="__element">...</div>
    </div>
</template>
Run Code Online (Sandbox Code Playgroud)

或增加wrapper__element一个额外的__element类(如果你可以忽略重复):

<!-- MyComponent.vue -->
<template>
    <div class="wrapper">
        <div class="wrapper__element __element">...</div>
    </div>
</template>
Run Code Online (Sandbox Code Playgroud)

由于某种原因,这种情况需要:deep基于选择器(例如,root在下面的示例中):

<!-- MyParent.vue -->
<template>
    <div class="root">
        <MyComponent />
    </div>
</template>

<style scoped lang="scss">
.root:deep(.wrapper) {
    display: flex;

    .__element {
        display: block;
    }
}
</style>
Run Code Online (Sandbox Code Playgroud)
<!-- MyComponent.vue -->
<template>
  <div class="wrapper">
    <h1>.wrapper</h1>

    <!-- Add __element class here  (and optionally remove wrapper__element) -->
    <div class="wrapper__element __element">
      <h1>.wrapper__element</h1>
    </div>
  </div>
</template>
Run Code Online (Sandbox Code Playgroud)

演示2