- Vue文件的
<style></style>
进行编译时, 如果没有加scope
限定, 就不会在当前template
生成的DOM元素上添加[data-v-xxx]
属性, 里面定义的样式也会在全局起作用 - 如果添加了
scope
限定, 会将<template>
中的每个元素加入[data-v-xxxx]
属性来确保style scoped
仅本组件的元素而不会污染全局
加了scope后会有一个问题: 如果在当前组件中又嵌入了子组件, 那么子组件标签上添加的class
都会被添加到子组件的根节点上, 并且子组件上有父组件的data-v
, 如果子组件内部也有style scope
, 则还会添加上自己的data-v
此时, 如果在父组件中通过.main .sub .sub-el
的方式修改样式, 不会生效. 因为编译后的CSS中, 选择器是: .mine-container .my-video .sub-el[父组件data-v]
, 而子组件中元素添加的是[子组件data-v]
, 所以找不到元素:
<!-- 父组件 -->
<div class="wrapper">
<MySubCom title="性别" class="subcom"></MySubCom>
</div>
<!-- 子组件 -->
<div class="sub"><span>子组件</span></div>
<style scoped>
/* 父组件 */
.wrapper .subcom span {
color: red;
}
</style>
上面的例子中, span
的颜色样式不会生效, 因为编译后的选择器是: .wrapper .subcom span[当前组件data-v]
这样设计的目的是, 可以调整子组件在父组件中的布局, 同时不会影响子组件内部的布局
解决方法一
将 scoped 移除,或者新建一个没有 scoped 的 style(一个vue文件允许多个style), 没有scope的限制时, 元素不会添加data限制属性
<style scoped>
.wrapper {
// ...
}
</style>
<style>
.wrapper .weui-cells {
// ...
}
</style>
解决方法二: 深度作用选择器
深度作用选择器 >>>
, 只作用于Vue编译环境中的纯css
<style scoped>
.wrapper .subcom >>> span {
color: red
}
</style>
如果是sass/less的话可能无法识别,这时候需要使用 /deep/
选择器。
<style lang="scss" scoped>
.wrapper {
.subcom /deep/ span {
color: red;
}
}
</style>
- 如果
/deep/
使用vue/cli
编译后有警告, 可以替换为::v-deep
指令
原理: 深度选择器左侧的选择器一定要是编译后带有data-
属性的元素, 其实就是用该元素对深度选择器右侧的元素进行了定位
注意: 深度作用选择器的原理是, 在编译时, 会把深度选择器替换成[data-v]
, 而不会再在子组件元素后面添加该选择器, 比如上面的例子中, 最后编译的结果是: .wrapper .subcom[当前组件data-v] span
, 所以选择器可以成功找到span
, 从而样式生效.
同样的, 也可以把/deep/
放在.wrapper
后面, 结果是: .wrapper[当前组件data-v] .subcom span
千万不要把/deep/
放在子组件元素后面, 比如放在span后面结果就是: .wrapper .subcom span[当前组件data-v]
, 肯定就找不到span
尽量不要把/deep/
放在最前面, 最前就是: [当前组件data-v] .wrapper .subcom span
, 如果.wrapper
是当前组件的根节点class, 也会找不到span, 如果不是, 则可以找到span