Vue中模块和作用域样式有什么区别?

28

<style module><style scoped> 在Vue中有什么区别?

官方文档(link1link2)仅说明 scoped 使用 PostCSS 转换,而 module 使用CSS Modules。但两者之间的真正功能区别是什么呢?

(注意:如果它们使用的 PostCSS 转换是该插件,它实际上使用了 CSS Modules……)

2个回答

44

它们都是处理作用域 CSS 的方式,实现的功能基本相同。但它们的处理方式有些不同。

在 Vue 中,作用域样式只是普通的 CSS,但添加了一些额外的类来限定作用域。它类似于 Shadow DOM,在组件中限定作用域。这种方法的好处是你可以像平常写 CSS 一样继续编写,但如果需要,你还可以获得一些额外的作用域限制。

CSS Modules 则使用 Webpack 根据块和类编译唯一的类名。它自动创建唯一的 BEM 类。它在 CSS 方面拥有许多附加功能(您不必使用)。

CSS Modules 不是 Vue 特有的东西,因此,如果你学会了,你可以将其应用于任何构建中,只要你可以导入 CSS 模块。然而,Vue 的 CSS 作用域非常简单,如果你知道 CSS,实际上没有什么额外需要学习的(只有一些选择器)。

CSS Modules 类名将被 Webpack 构建为.{component}__{className}__{randomHash}

Vue 作用域 CSS 将由 postcss 构建为 .{className}[data-v-{componentHash}]。该componentHash 应用于该组件中的每个元素。

两种方法都基于哈希和类名编译 CSS。作用域 CSS 还向 HTML 添加了附加数据属性以进行作用域限制。CSS Modules 使用 JavaScript 更多地管理样式。

尽管两者做的事情都差不多,但对我来说唯一的区别就是类的创建方式。我猜CSS Modules由于所有类的特异性更低,所以应该更具性能优势,但这确实取决于编写CSS的人。就我个人而言,我会坚持使用更简单的那个(我将让您决定哪一个是更简单的)。


好的,从功能上来说它们差不多是等价的。但是,从你的回答中我并没有清楚地了解到它们如何“稍微有些不同”。 - Robert Kusznier
我已经添加了更多关于类的结构以及它们如何构建的信息。 - Adam Hughes
7
谢谢。我也自己阅读了一些内容。你没有详细解释的另一个显著区别是如何在HTML中应用类。在CSS Modules中,您需要使用带有绑定的JavaScript对象(:class="$style.className"),而在Scoped样式中,您正常应用类(class="className")。 - Robert Kusznier
3
我想补充一点,使用作用域样式可能会遇到一个大问题,那就是使用外部库或全局样式。在组件中使用的类将按原样传递。因此,一个无辜的.wrapper[data-v-54321]类也会应用任何全局/外部.wrapper类的CSS。通常这是一个display值...好吧,前方有趣的时光!:D - HerrSiering
补充@HerrSiering的观点——如果你正在开发一个共享组件并希望将其作为样式覆盖的黑匣子:CSS模块将混淆您的类,这对消费者来说更难选择/覆盖。 - Pavel Gurecki

0
模块是比Scoped更安全的选项来限定CSS的作用域。
在Scoped模式下,你的CSS类会附加一个data-v属性,例如.button[data-v-9ad5ab0c]。(data-v属性是由Vue添加到你的HTML元素中的)
因此,应用样式的特异性更高,但同时,如果在你的代码的其他地方有.button类的样式,它们也会被应用(假设它们没有被应用到.button[data-v-9ad5ab0c]的样式覆盖)。
模块。在这种模式下,你的.button类会被修改为类似._button_vdpj6_2的哈希值。
这样,你就可以为你的元素获得一个唯一的类,不会影响到其他具有.button类的元素。而.button的样式也不会影响到你正在设置样式的元素。

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