样式穿透之Scoped1
第一节
css作为前端最主要的技术之一,相信小伙伴对它都不陌生,但当我们接触到像vue这种工程化项目的时候,可能小伙伴会有很多疑问,为什么style标签会添加scoped属性,它有什么作用嘛,为什么有些样式会在前面添加::v-deep,这个属性又是做什么用的?
简单来说scoped就是私有化页面样式,而::v-deep就是在当前页面下,可以修改私有化以外的样式。
接来下我们将从外到里的来了解一下它们,使得当我们下次再遇到类似问题的时候,可以快速的解决。
首先,我们先来了解一下scoped样式
1. scoped样式的作用
2. scoped样式解决了什么
这里准备了两个vue页面scoped1.vue、scoped2.vue
<!-- scoped1.vue -->
<template>
<div style="text-align: center; font-size: 34px;">
<a href="https://www.baidu.com">百度</a>
</div>
</template>
<!-- scoped2.vue -->
<template>
<div style="text-align: center; font-size: 34px;">
<a href="https://cn.bing.com">必应</a>
</div>
</template>
<script>
接下来,我想把这个必应的a标签设置一个红色,百度先暂时不加
a {
color: red;
}
然后我们看到,两个页面都变成红色了,为什么呢?我们来看一下页面的元素

首先我们先打开一个这个页面刷新一下,把body标签关上,我们来展开看一下head标签。
默认情况下,我们还没有打开那两个页面的时候,已经默认加载了这些style和script,然后我们现在打开必应的页面,这里发现,head里面多了一行style,在这里面就是我们刚刚写的a标签样式,这个时候,样式已经被加载到了页面上了。

这时候我们在打开百度页面,这时候虽然百度页面没有写style,但是百度页面也有a标签,所以它遵循了这个color样式,变成了红色,如果我们先打开百度页面呢?这时候百度页面还是正常的。但这时候如果我再打开一次必应页面再回来,这时候必应的style就被加载进来了,百度页面color又变成红色了。
到此为止,我们很容易理解产生这个问题的原因,因为他是单页面应用,所以我们打开的每一个页面的style,都会被加载到全局的样式里面,从而导致了不同页面的样式会乱。
那么怎么解决这个问题呢?—— 就是用scoped
我们看,现在这个百度的a标签里面是没有data-v-xxx的

现在我们把它加上一个scoped,必应的a标签也加上。

这个时候我们在刷新看一下,大家看这个a标签,现在多了一个data-v-71a7f2bc,这个是什么呢,这个就是vue替我们加上的,vue在构建这个项目的时候会替我们以组件为单位,不同的组件下,所有的元素都会添加上同一个这个类似于组件id一样的东西,同时,vue也会在我们写的样式上,以属性选择器的方式,拼接上这个唯一标识。
我们来验证一下
大家看这个a标签的样式,后面多了一个[data-v-xxxx],它代表着有这个属性的a标签,才会遵循我们这个样式,就只有必应这个页面下的所有元素,才有这个属性值,从而来实现不同页面的样式的隔离,而且vue只会把这个属性选择器拼接到最后一段,假如我们这个a标签上面还有一层
div a {
color: red;
}
这里我们看,div是不会帮我们拼接[data-v-xxxx]属性的,只有最里层的a标签会有这个属性,除非有逗号的情况,因为逗号它就是另一个样式,这里的table也会被添加上[data-v-xxxx]
div a, table {
color: red;
}
那总结起来的话,就是当我们用了scoped样式以后,vue会在构建项目的时候做两件事,第一它会以组件为单位,在组件内部所有的元素上加上这个唯一标识的属性,第二他会把我们声明的样式最后一段,拼接上这个唯一的标识,从而来实现不同页面的样式的隔离。
所以小伙伴再做vue项目的时候,不要被它标签上的[data-v-xxxx]所搞晕了
后面我们将看一下用了scoped以后会有什么副作用,以及我们怎么用这个样式穿透来解决它