在 VueJS 模块中嵌套 SCSS 规则

Posted

技术标签:

【中文标题】在 VueJS 模块中嵌套 SCSS 规则【英文标题】:Nesting SCSS Rules in VueJS Modules 【发布时间】:2019-07-21 11:24:49 【问题描述】:

在处理 CSS 模块以将样式导入本地组件时,如何处理嵌套的 SCSS 规则,这些规则扩展了基本样式?

就我而言,我有以下两个 SCSS 文件:

icon.scss

.my-icon 
  // base styles for an icon

button.scss

.my-button 
  ...
  .my-icon 
    // special styles when an icon is in a button
  

然后我将其导入到它们各自的组件中:

MyIcon.vue

<template><i class="my-icon" /></template>
<style lang="scss" module>
@import '/path/to/icon.scss'
</style>

MyButton.vue

<template><button class="my-button"><slot /></button></template>
<style lang="scss" module>
@import '/path/to/button.scss'
</style>

问题在于 嵌套 .my-icon 类,在 'button.scss' 中,与根 .my-icon 类,在 'icon. scss' (._2UFd)。因此,当我尝试将图标嵌入到按钮中时,我会得到如下所示的输出:

<button class="._3S2w"><i class="._2UFd" /></button>

这是正确的,但未应用按钮中图标的“特殊样式”,因为该类是作为不同的哈希生成的。

如何确保 '.my-icon' 的哈希值始终相同?

【问题讨论】:

我还没有见过像这样嵌套的 vanilla CSS。 AFAIK 只有 Less、SASS 或其他 CSS 预处理器明白这一点,但 CSS 不明白 您不能在 CSS 中嵌套规则 - 这仅在您使用 SASS / LESS 时有效。你在使用 webpack 和单文件组件 vuejs.org/v2/guide/single-file-components.html 吗?如果是这样,在您的单个文件组件的 &lt;style&gt; 标记中,您应该能够添加 &lt;style lang="scss"&gt; 并使其与 SASS 样式规则一起使用。不过,我只在 Laravel Mix 环境中使用过 Vue,所以你可能需要一些额外的依赖项/webpack 配置才能使这部分工作。此外,如果您在组件中启用了 SASS,请确保这些组件实际上具有类。 糟糕——是的,它是 SASS。两个 .my-icon 类在最终代码中生成不同的哈希,因此嵌套的图标组件没有选择正确的样式。 当您在组件中使用作用域样式 (&lt;style scoped&gt;) 时,只有该组件会应用这些样式,甚至嵌套组件都不会应用它们,所以如果您想设置嵌套样式来自父级的组件,作用域样式将不起作用(如果您正在使用它们)。 进行了编辑,希望能让事情更清楚。 【参考方案1】:

在某个地方,隐藏在 Vue 加载器的深处,文档简要地讨论了如何逃避作用域样式。解决方案是使用a /deep/ selector,由 scss 预处理,使其后面的所有内容都没有散列。普通的 css 中也有类似的东西,但有些无关。

假设我们有我们的my-button 组件并想要在其中设置my-icon 类的样式,我们可以执行以下操作:

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

<style lang="scss" scoped>
/deep/ .my-icon 
  background: red;

</style>

以下内容应生成类似以下内容。它仍然在您的组件范围内,但.my-icon 不必是您的组件的一部分。在这种情况下,例如,它可能在插槽内。

[data-v-f3f3eg9] .my-icon 
  background: red;

【讨论】:

这看起来很有希望;我很快就能试试。我在外部 SCSS 文件中使用 module 而不是 scoped@import - 你知道这是否同样适用吗? 我不确定。我只是在本月早些时候才知道/deep/,当时一位同事将它放在合并请求中,但我不知道它做了什么。不过还是挺好看的。 看起来不像 /deep/ 与模块一起使用。 :( 至少在文件导入时,我的文件中只输出了一个“/deep/”。真可惜。

以上是关于在 VueJS 模块中嵌套 SCSS 规则的主要内容,如果未能解决你的问题,请参考以下文章

使用 SASS 嵌套的优点

SCSS学习手册

SCSS--SCSS 常用属性合集

我可以扩展外部 scss 规则而不将其包含在输出中吗?

VisibleDeprecationWarning:从不规则的嵌套序列创建一个 ndarray

LEGB规则