一个style
标签拥有scoped
属性时,css样式就只能作用于当前的组件,这样就可以使得组件之间的样式不互相污染。如果一个项目中的所有style
标签全部加上了scoped
,相当于实现了组件的私有化,样式的模块化。
原理
scope
的本质是分别给 HTML
标签和 CSS
选择器添加 data-v-xxx
,来达到样式隔离的效果。
data-v-hash
值data-v-hash
的属性选择器样式穿透问题
使用 scoped
后,父组件是没有办法修改子组件中的样式(除了子组件根节点)
如果在父组件中设置样式div span
,那么父组件该样式的优先级高一点,所以span
是黑色
//父组件css
span{
color: black;
}
//子组件html
<template>
<span >
子组件
</span>
</template>
//子组件css
.children span{
color: blue;
}
//父组件css
div .children span{
color: black; //样式没生效
}
//子组件html
<div class="children">
<span >
子组件
</span>
</div>
//子组件css
.children span{
color: blue;
}
此时,父组件的样式没有生效
作用:scoped
的样式可以作用得更深,比如影响子组件。
vue2中穿透的方法:::v-deep
>>>
和/deep/
已弃用。
::v-deep .el-col {
margin-bottom: 20px;
}
vue3穿透的方法:deep(.className)
官方推荐:deep(.el-col)
深度选择器。
::v-deep(.el-col) {
margin-bottom: 20px;
}
// 缩写
:deep(.el-col) {
margin-bottom: 20px;
}
在上面的案例中,.children
是子组件的根元素可以获取到,我们也可以看见.children
标签上有子组件的hash值。所以需要穿透的是span
属性。
//父组件
div .children :deep(span){
color: black;
}
//解析出来时
div .children[data-v-7a7a37b1] span{
color: black;
}
由此可见:deep()
的原理就是在前面添加[data-v-hash]
。
所以如果使用deep
的样式节点没有父节点,这种用法是没有意义的。使用deep之后解析的代码为[data-v-hash] 节点
。
原因是没有父节点说明本身就是该组件的根元素,那么父组件可以修改其样式