样式隔离
loyalvi Lv7

样式隔离

vue中Scoped Styles是如何实现样式隔离的

在Vue中,scoped样式是通过在单文件组件(Single File Components, SFC)的<style>标签中添加scoped属性来实现样式隔离的。以下是其实现原理:

实现原理

  1. 生成唯一的作用域ID
    • Vue为每个带有scoped属性的组件生成一个唯一的作用域ID,例如data-v-f3f3eg9。这个ID是随机生成的,确保每个组件的作用域ID是独一无二的。
  2. 添加作用域ID到模板元素
    • 在编译组件模板的过程中,Vue会将这个作用域ID作为自定义属性添加到组件模板的所有元素上。例如,如果作用域ID是data-v-f3f3eg9,那么在该组件模板的所有元素上都会添加一个属性data-v-f3f3eg9
  3. 修改CSS选择器
    • 对于组件内部的每个CSS规则,Vue会自动转换其选择器,使其仅匹配带有对应作用域ID的元素。这是通过在CSS选择器的末尾添加相应的作用域ID属性选择器来实现的。例如,如果CSS规则是.button { color: red; },并且作用域ID是data-v-f3f3eg9,那么该规则会被转换成.button[data-v-f3f3eg9] { color: red; }

示例

假设有一个Vue组件如下:

1
2
3
4
5
6
7
8
<template>
<div class="example">hi</div>
</template>
<style scoped>
.example {
color: red;
}
</style>

编译后,CSS和HTML会被转换为:

1
<div class="example" data-v-f3f3eg9>hi</div>
1
2
3
.example[data-v-f3f3eg9] {
color: red;
}

这样,.example样式规则只会应用到当前组件中的<div>元素上,而不会影响到其他组件中的同类元素。

注意事项

  • 性能影响:由于样式隔离是通过属性选择器和自定义属性实现的,这种方法的性能可能会略低于全局样式规则。
  • 子组件样式scoped样式不能影响子组件,仅限于当前的组件。如果需要影响子组件,则可以使用深度选择器(如>>>/deep/)。
  • 全局选择器:如果想让其中一个样式规则应用到全局,可以使用:global伪类。

Scope如何避免组件之间样式的冲突

在Vue中,scoped属性是<style>标签的一个特殊属性,它用于确保样式只应用于当前组件的元素,从而避免样式冲突。以下是scoped属性如何工作以及如何使用它的一些细节:

如何工作

当在Vue组件的<style>标签中使用scoped属性时,Vue会自动将样式应用到当前组件的根元素(或多个根元素)。Vue通过动态生成唯一的ID,并使用CSS选择器的属性选择器(例如[data-v-f3f3eg9])来实现这一点。这样,所有的CSS规则都会限定在这个ID的作用域内。

使用方法

  1. 基本用法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<template>
<div>
<h1>这是一个标题</h1>
<p>这是一个段落。</p>
</div>
</template>
<script>
export default {
// 组件逻辑
};
</script>
<style scoped>
h1 {
color: red;
}
p {
color: blue;
}
</style>

在这个例子中,h1p的样式只会应用于当前组件内的h1p元素,而不会影响到其他组件中的h1p
2. 深度选择器
有时候,你可能需要对子组件的元素应用样式,即使它们不是直接的子元素。在这种情况下,你可以使用深度选择器>>>(或/deep/::v-deep)来穿透scoped的作用域。

1
2
3
4
5
<style scoped>
div >>> p {
color: green;
}
</style>

这将使得div内部的所有p元素(包括子组件中的p元素)都应用这个样式。

注意事项

  • scoped样式不会穿透组件边界:这意味着scoped样式不会应用到子组件的根元素上,除非你使用深度选择器。
  • scoped样式对模板中的所有元素有效:如果你的模板中有多个根元素,scoped样式将应用到所有这些根元素上。
  • scoped样式与CSS Modules的区别scoped样式是Vue特有的,而CSS Modules需要构建工具的支持,并且可以在非Vue项目中使用。
  • scoped样式与预处理器:如果你使用SASS或LESS等CSS预处理器,scoped属性同样适用,但是你需要确保预处理器的编译结果符合Vue的scoped样式规则。
    使用scoped属性是Vue中避免组件间样式冲突的一种简单有效的方法,它通过自动生成的作用域ID来确保样式的局部性。
由 Hexo 驱动 & 主题 Keep
访客数 访问量