描述
vue中可以在style标签上增加属性 scoped,来达到“当前组件定义的样式不会影响其他组件的样式”的效果。同时还可以对特殊的样式选择器单独配置/deep/
>>>
::v-deep
来打破这种限制。
使用
<!-- 编译前 -->
<div class="container"></div>
<style scoped>
.container{...}
</style>
<!-- 编译后 -->
<div class="container" data-v-3kgjsjn4></div>
<style>
.container[data-v-3kgjsjn4]{...}
</style>
- 如果你没有使用css与编译器,而是普通的css(style 上没有 lang=“less/scss…”),那么你可以使用
>>>``/deep/``::v-deep
- 如果是用了
less``scss
那么就不能使用>>>
了,而只能用/deep/``::v-deep
- 高版本的vue建议使用
deep()
代替::v-deep
<style scoped>
.container{
/* & >>> #childClassName{} 通过>>>可以打破scoped的限制,将样式应用到子组件 */
}
</style>
<style scoped lang="less">
.container{
/* & /deep/ #div{} */
/* & ::v-depp #div{} */
/* ... */
}
</style>
原理
vue相关的一系列loader会为style带有scoped属性的组件生成scopedId
,这个id是根据组件的路径和组件内容生成的。然后会为当前组件内的所有标签应用该属性data-v-scopedId
,同时在postcss的作用下,样式组合选择器的最后一个选择其加上属性选择data-v-scopedId
如果是用了样式穿透,那么postcss不会为他加上scopedId
属性选择器
<style scoped lang="less">
.container .menus li{
...
}
</style>
<style scoped lang="less">
.container .menus li[data-v-scopedId]{
...
}
</style>
这是一个组合选择器:.container .menus>li
li
这是组合选择器的最后一个选择器,为他加上属性选择器得到:
.container .menus>li[data-v-scopedId]
,这样就将li
限制在当前组件范围的 li