结论先行:
为了达到组件样式模块化。也就是让样式作用域仅限于当前组件中,不影响全局,避免了样式污染和样式冲突的问题。
它的底层实现逻辑呢,
就是生成一个唯一的 data 属性作为标识,例如 data-v-xxx 并添加到 DOM 节点上。然后再通过属性选择器的方式,拿到这个全局唯一标识来私有化样式。
Scoped 是指在 CSS 中通过特定的方式限定样式规则的作用范围,使得样式只作用于特定的组件或元素,而不会影响到其他组件或元素。在 Vue 和 React 等前端框架中,Scoped CSS通常是通过加入特定的选择器来实现的。
在 Vue 中使用 scoped 属性可以让样式作用域仅限于当前组件中,不影响全局,避免了样式污染和样式冲突的问题。
在组件中使用 scoped 的方式如下:
- <template>
- <div class="example">Example Componentdiv>
- template>
-
- <style scoped>
- .example {
- color: red;
- }
- style>
在这个例子中,.example 样式规则只会作用于当前组件内部的元素,而不会影响全局的样式。
为了达到组件样式模块化,做了两个处理:
① scoped 会为每个组件的 DOM 节点添加一个唯一的 data 属性(例如: data-v-5558831a)作为标记;
② css样式上是通过 data 属性选择器([data-v-2311c06a])的方式来私有化样式。
Vue中的 scoped 属性的效果主要是通过 PostCss 实现的。
在 Vue 中,Scoped CSS 是通过给每个组件的 style 标签添加一个唯一的属性选择器来实现的,例如
。
以下是转译前的代码:
- <template>
- <div class="example">testdiv>
- template>
-
- <style scoped lang="sass">
- .example {
- color:red;
- }
- style>
转译后:
当使用 scoped 修饰符时,Vue会将组件内部的样式规则自动转化为带有该属性选择器的选择器。这样一来,样式规则只会应用于当前组件的 DOM 元素及其子元素,而不会泄漏到其他组件。
- .example[data-v-1121845a] {
- color: red;
- }
- <template>
- <div class="example" data-v-1121845a>testdiv>
- template>
上述代码中的
[data-v-1121845a]
就是添加的唯一属性选择器,它用来保证样式仅作用于当前组件内的元素。这样,只有该组件内部的 example 类会应用该样式规则,其他组件的不受该样式影响。
即:PostCSS 给一个组件中的所有 DOM 添加了一个独一无二的动态属性,给 css 选择器额外添加一个对应的属性选择器,来选择组件中的 DOM,这种做法使得样式只作用于含有该属性的 DOM 元素(组件内部的 DOM)。
需要注意的是,Scoped CSS 只对当前组件的样式起作用,不会影响到子组件或父组件的样式。
如果需要在子组件中使用 Scoped CSS,需要单独为子组件的模板添加scoped修饰符。
总结来说,Scoped CSS通过为样式选择器添加唯一的属性选择器,限定样式规则的作用范围,使得样式只作用于特定的组件或元素。
这种方式可以避免样式冲突,提高样式隔离性,是前端框架中常用的一种样式隔离解决方案。