1.什么是scoped
在Vue文件中的style标签上有一个特殊的属性,scoped。当一个style标签拥有scoped属性时候,它的css样式只能用于当前的Vue组件,可以使组件的样式不相互污染。如果一个项目的所有style标签都加上了scoped属性,相当于实现了样式的模块化。
2.scoped的实现原理
scoped主要用于vue中style部分,加上scoped后,最终生成的dom和style都会被加上一个唯一的动态属性,这样样式只会对当前组件有效,不会污染全局样式。
转译前的代码:
转译后:
总结:scoped的渲染规则:
-
给HTML的dom节点添加一个不重复的data属性(例如: data-v-5558831a)来唯一标识这个dom 元素
-
在每句css选择器的末尾(编译后生成的css语句)加一个当前组件的data属性选择器(例如:[data-v-5558831a])来私有化样式
3.对于上面两条规律,父组件内引入子组件的情况下,是否一样呢?这里直接给出结果!
1.情况一 ( 父子组件样式都有scoped ):
所有DOM元素都会添加标识,不影响
2.情况二 (子组件样式没有scoped 重点!!!)
虽然我们写的子组件大部分都是带有scoped的,但是常用的组件库,比如element、vux、vant提供的组件是不带scoped的!此情况总结如下:
1.父组件内出现的dom标签都会被添加上同一个属性值,包括给子组件传入的slot内容;
2.父组件的属性值只会设置在子组件的最外层,并不会设置到子组件的内部dom元素上;
这样父组件就只能修改子组件最外层的div样式,但是修改子组件内层元素的样式是不可行的。!
想要修改子组件的内层元素样式,就需要使用/deep/了,使用/deep/
深度选择器会在css中加上[data-v-hash]
这个父代选择器来控制子组件样式,如[data-v-hash] .el-card__header。