vue组件样式穿透

在应用vue开发前端项目时,有时候我们需要在父组件中改变子组件的默认样式,比如你的项目中引用了第三方UI库,但是你觉得某个组件的样式你并不喜欢,那么你想改变它的默认样式,那么我们该怎么办呢?

直接上代码,先来看父组件Home.vue的代码

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
// 父组件Home.vue
<template>
<div class="home">
<h1>This is Home Component!</h1>
<HelloWorld/>
</div>
</template>

<script>
// @ is an alias to /src
import HelloWorld from "@/components/HelloWorld.vue";

export default {
name: "home",
components: {
HelloWorld
}
};
</script>

<style scoped>
h1 {
color: brown;
}
</style>

再来看子组件HelloWorld.vue的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 子组件HelloWorld.vue
<template>
<div class="hello">
<h2 class="title">This is HelloWorld Component!</h2>
</div>
</template>

<script>
export default {
name: "HelloWorld",
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.title {
color: #42b983;
}
</style>

那么,我们先来看一下页面的效果:

那么,接下来,我们如果想要在Home.vue中写样式想要改变其子组件HelloWorld.vue中”This is HelloWorld!”这句话的某个样式,比如说字体颜色,那么,我们该怎么办呢?

如果,我们直接在Home.vue的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
// Home.vue组建
<template>
<div class="home">
<h1>This is Home Component!</h1>
<HelloWorld/>
</div>
</template>

<script>
// @ is an alias to /src
import HelloWorld from "@/components/HelloWorld.vue";

export default {
name: "home",
components: {
HelloWorld
}
};
</script>

<style scoped>
h1 {
color: brown;
}
.home .title {
color: rebeccapurple;
}
</style>

直接在Home.vue中想要控制子组件的样式,直接这样写,明显是不会生效的!

vue2.x的组件样式穿透写法

那么,我们该怎么办呢?此时,我们可以使用深度作用选择器,如果你希望组件 scoped 样式中的一个选择器能够作用得“更深”,例如影响子组件,你可以使用 >>> 操作符:

比如就上述例子而言,你可以Home.vue中scoped的样式改为下面这样:

1
2
3
4
5
6
7
8
<style scoped>
h1 {
color: brown;
}
.home >>> .title {
color: rebeccapurple;
}
</style>

如此,将会达到我们想要的效果拉了!看下页面效果:

可以看到,子组件的字体颜色已经改变了!

如果是有些像 Sass、less 之类的预处理器无法正确解析 >>>。这种情况下你可以使用 /deep/ 操作符取而代之——这是一个 >>> 的别名,同样可以正常工作。如下:

1
2
3
4
5
6
7
8
9
10
<style scoped lang="scss">
h1 {
color: brown;
}
.home {
/deep/ .title {
color: rebeccapurple;
}
}
</style>

vue3.x的组件样式穿透写法

1
2
3
4
5
6
7
8
9
10
<style scoped lang="scss">
h1 {
color: brown;
}
.home {
:deep(.title) {
color: rebeccapurple;
}
}
</style>

注意:vue3.x已经删除了 /deep/ 和 >>> 操作符,请务必使用:deep()进行组件样式穿透。