前言
平时开发项目我们在使用第三方插件时,必须使用element-ui、van-ui等的某些组件需要修改样式时,老是需要加上/deep/深度选择器,以前只是知道这样用,但是还不清楚他的原理。还有平时每个组件的样式都会加上scoped,但是也不知道他具体的原理。
1. Scoped CSS的原理
1.1 无scoped
如代码:
<template>
<div class="hello-world">
<div class="hello-world-box">深度选择器</div>
</div>
</template>
<style lang="scss" >
// 不加scoped
.hello-world {
&-box {
width: 200px;
height: 200px;
background-color: antiquewhite;
}
}
</style>
没有什么特殊,直接渲染
1.2 有scoped
如代码:
<template>
<div class="hello-world">
<div class="hello-world-box">深度选择器</div>
</div>
</template>
<style lang="scss" scoped>
// 加scoped
.hello-world {
&-box {
width: 200px;
height: 200px;
background-color: antiquewhite;
}
}
</style>
可以看到多了一个data-v-hash
属性,也就是说加了scoped,PostCSS
给一个组件中的所有dom添加了一个独一无二的动态属性,然后,给CSS选择器额外添加一个对应的属性选择器来选择该组件中dom,这种做法使得样式只作用于含有该属性的dom——组件内部dom,可以使得组件之间的样式不互相污染。
1.3 原理
vue中scoped的作用:
实现组件的私有化,当前style属性只属于当前模块
但是当我们使用公共组件的时候会造成很多困难
scoped的实现原理:
在DOM结构中可以发现,vue通过在DOM结构以及css样式上加了唯一标记,达到样式私有化,不污染全局的作用,可以看出加上scoped后的组件里的会多data-v-469af010
属性, css样式中可以看出;
1.给DOM节点加一个不重复属性 data-v-469af010
标志唯一性
2. 使每个样式选择器后添加类似于"不重复属性"的字段,类似于作用域的作用,不影响全局。
3. 如果组件内部还有组件,只会给最外层的组件里的标签加上唯一属性字段,不影响组件内部引用的组件。
2. >>>、/deep/、::v-deep深度选择器的使用
在vue页面使用scoped
,而又想修改组件样式时,可以使用 >>>
、/deep/
、::v-deep
这三个深度选择器来修改
// 第一种
/deep/ .van-tab {
font-size: 20px;
font-weight: 600;
}
// 第二种
>>>.van-tab {
font-size: 20px;
font-weight: 600;
}
// 第三种
::v-deep() {
.van-tab {
font-size: 20px;
font-weight: 600;
}
}
3. 深度选择器无效时,怎么办
如果上面三种方法都无法修改van-tab的样式,可能去掉scoped
,给当前vue页面的根元素,加上id或者class,同时使用 <style lang="scss" >
,如:
<template>
<div class="hello-world">
<div class="hello-world-box">
深度选择器
</div>
<van-tabs v-model="active">
<van-tab title="标签 1">内容 1</van-tab>
<van-tab title="标签 2">内容 2</van-tab>
<van-tab title="标签 3">内容 3</van-tab>
<van-tab title="标签 4">内容 4</van-tab>
</van-tabs>
</div>
</template>
<style lang="scss">
.hello-world { // 使用根元素的class,来限制只能是 hello-world 该类名下,才能起效,也可以避免全局污染
&-box {
width: 200px;
height: 200px;
background-color: antiquewhite;
}
.van-tab {
font-size: 20px;
font-weight: 600;
}
}
</style>
如下:在没有scoped
时,成功修改了tab标签文本