scoped与deep原理
# 前置知识
# CSS属性选择器 (opens new window)
HTML允许给DOM元素设置属性(<p bg-red>属性</p>
)或属性值(<p data=“red”>属性值</p>
),通过属性进一步选择元素,修改其样式。
<!DOCTYPE html>
<html>
<head>
<style>
p[bg-red] {
background-color: red;
}
p[fontColor="red"] {
color: red;
}
</style>
</head>
<body>
<p bg-red>文本一</p>
<p fontColor="red">文本二</p>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
效果如图:
# scoped原理
vue中scoped主要通过postcss (opens new window)实现的,转译代码时postcss做了如下处理:
- 给每个DOM节点添加一个唯一的属性(如:data-v-a0901)
- 在css选择器末尾加上对应的属性选择器(如:.user[data-v-a0901]),来私有化样式
如果组件内包含其他组件,只会给其他组件的最外层标签加上当前组件的data属性
转译前
<style scoped lang="sass">
.example {
color: red;
}
</style>
<template>
<div class="example">scoped测试案例</div>
</template>
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
转译后
<style scoped lang="sass">
.example[data-v-5558831a] {
color: red;
}
</style>
<template>
<div class="example" data-v-5558831a>scoped测试案例</div>
</template>
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
这样也就达到了样式模块化的目的。
# scoped产生的影响
当我们想去改组件库样式(如elementUI)时,会发现修改不成功了。
<style lang="scss" scoped>
.container{
background: #fff;
.ep-rate{
background: black;
.ep-rate__item{
background: red;
}
}
}
</style>
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
转译后
.container[data-v-7ba5bd90] { background: #fff; }
.container .ep-rate[data-v-7ba5bd90] { background: black; }
.container .ep-rate .ep-rate__item[data-v-7ba5bd90] { background: red; }
1
2
3
2
3
这时候会发现,想要改组件库的样式改不掉了,只改掉了第一层,因为引入其他组件,只会在最外层加上私有属性,所以ep-rate
的样式可以修改成功。
那在scoped
中如何修改组件库样式呢?这就要用到深度选择器
了,继续往下看。
# vue中深度选择器
deep的原理就是将私有属性移到上一层
<style lang="scss" scoped>
// .container[data-v-7ba5bd90]
.container{
background: #d7d7d7;
// .container .box2[data-v-7ba5bd90]
.box2{
width:100px;
height: 100px;
// .container .box2 .ep-button[data-v-7ba5bd90]
.ep-button{
background: red;
}
// .container .box2[data-v-7ba5bd90] .ep-button
:deep(.ep-button){
background: #00a6ff;
border: none;
}
}
:deep{
// .container[data-v-7ba5bd90] .ep-rate
.ep-rate{
background: #000000;
// .container[data-v-7ba5bd90] .ep-rate .ep-rate__item
.ep-rate__item{
background: #4eff10;
}
}
}
}
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
可以看到,加deep
深度选择器后,deep内的class都没加私有属性,而是把私有属性提升到了deep的上一层,这样就可以修改组件库样式了。
编辑 (opens new window)
上次更新: 2023/02/08