在我们使用vue进行web项目开发的时候,每一个vue文件都对应了一个页面,在这个vue文件中包含了页面渲染标签、js逻辑处理和css样式几个部分。整体的结构如下:
<template>
<div class="example">{{ msg }}</div>
</template>
<script>
export default {
data () {
return {
msg: 'Hello world!'
}
}
}
</script>
<style
>
</style>
在样式设置这里,通常情况下都会有上述的两种设置方式。当style标签加上scoped属性时,css的样式只作用于当前组件中的页面元素,不会对整体的其他页面样式造成污染,当我们查看编译后的文件会发现,scoped的实现原理就是在组件样式中添加了一个随机属性而已,这样就实现了所谓的私有作用域效果;而不加scoped属性的样式则会作用于整体下的所有页面。
使用 scoped
后,CSS 只会作用于当前父组件中的元素,父组件的样式将不会渗透到子组件中。不过一个子组件的根节点会同时受其父组件的 scoped CSS 和子组件的 scoped CSS 的影响。这样设计是为了让父组件可以从布局的角度出发,调整其子组件根元素的样式。
使用scoped后,父组件的样式不会渗透到子组件内原因说明:scoped默认只会在父页面元素上加入这个 [data-v-xxxx] 随机属性,子组件内部元素上则不会添加这个随机属性,但所有的scoped中的css最终编译出的样式类名上都会有这个随机属性,导致页面元素上的class类名与编译后样式选择器类名不一致,所以样式作用不到子组件上
基于以上scoped属性的特性,在开发时我们可能会遇到这种情况:我们在当前页面中引入了第三方的组件,但这个第三方组件的默认样式并不符合我们当前页面想要展示的样式风格。此时我们可以有两种方式实现:方式1,将修改的第三方样式至于没有scoped属性的style标签下,解决了我们的问题,但随之带来了污染项目全局页面的问题。
这样就引出了第二种实现方式:CSS样式穿透(官方叫法-深度作用选择器)。它的主要作用是既能使用scoped属性保持样式的组件私有化,又能穿透到子组件内修改子组件的默认样式。写法有 >>> 和/deep/两种,语法如下:
.a >>> .b {...} 或
.a {
/deep/ .b{...}
}
使用样式穿透后,最终编译后的子组件css样式类b上就不会添加上述说的 [data-v-xxxx]这种随机属性,编译后样式类似.a [data-v-xxxx] .b{...}这样,与页面标签元素上的class类名一致,修改的子组件样式自然也就生效了