Vue style标签scoped属性与deep选择器原理

Posted 星云-

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue style标签scoped属性与deep选择器原理相关的知识,希望对你有一定的参考价值。

Scoped原理

vue项目中常在style标签上添加scoped属性避免全局污染,使得css只作用于当前的组件
代码解析scoped的作用原理

父组件

父组件
<template>
  <div class="father">
    father
    <child></child>
  </div>
</template>

<script>
import child from './child.vue'
export default 
  components: child 
;
</script>

<style lang="scss">
.father
  color: red;
  .child
    color: blue;
    .child-content
      color: green;
    
  

</style>

子组件

子组件
<template>
  <div class="child">
    child
    <div class="child-content">111</div>
  </div>
</template>

<style lang="scss">
.child-content
  font-size: 28px;

</style>

不加scoped属性编译之后

加上scopde属性之后

观察dom和css可以得出结论

  1. scoped底层是通过CSS 属性选择器实现的;
  2. 加上scoped后,dom会被添加上一个唯一的属性值,CSS中也会在css选择器尾部加上属性选择器[唯一属性值],这样使得样式只对该组件有效;
  3. 子组件只有最外层dom结构才加上了父组件的唯一的属性值,避免了全局样式污染(例子中的color:green不能作用到子组件中);

使用 scoped 后,父组件的样式将不会渗透到子组件中。不过一个子组件的根节点会同时受其父组件的 scoped CSS 和子组件的 scoped CSS 的影响。这样设计是为了让父组件可以从布局的角度出发,调整其子组件根元素的样式。

deep深度作用选择器

有些情况需要父组件的CSS作用到子组件,这时可以选择去掉scoped,但是会有全局样式污染的风险。

这种情况最好的做法是用deep深度作用选择器。
deep深度作用选择器有两种写法 /deep/ 或 ::v-deep

给上面例子中给父组件加上 /deep/

<style lang="scss" scoped>
.father 
  color: red;
  /deep/ .child
    color: blue;
    .child-content
      color: green;
    
  

</style>

编译结果

可以看到,属性选择器的位置移动到了father后面
对比一下加和不加的效果

可以看到属性选择器移动到.father后面以后,父组件的css就可以作用到子组件身上

对编译器来说 /deep/就是属性选择器的位置

我们可以控制/deep/的位置来达到控制子组件某个部位的样式,又不会污染整个子组件的样式

<style lang="scss" scoped>
.father 
  color: red;
  .child
    color: blue;
    /deep/ .child-content
      color: green;
    
  

</style>

编译后

<style lang="scss" scoped>
.father 
  color: red;
  .child
    color: blue;
    /deep/ .child-content
      color: green;
    
  

</style>

总结

style标签使用 scoped 后,父组件的样式将不会渗透到子组件中。不过一个子组件的根节点会同时受其父组件的 scoped CSS 和子组件的 scoped CSS 的影响。这样做可以避免CSS全局污染

如果你希望 scoped 样式中的一个选择器能够作用到子组件,可以在适当的位置使用 /deep/ 或 ::v-deep 操作符

以上是关于Vue style标签scoped属性与deep选择器原理的主要内容,如果未能解决你的问题,请参考以下文章

解析Vue中style标签scoped属性与deep选择器原理

CSS - scoped属性/深度作用选择器/deep/及>>>

vue样式加scoped后不能覆盖组件的原有样式解决方法

深度选择器

vue 中 style 标签中的 scoped 属性(作用域)和 lang 属性的介绍

vue 中 style 标签中的 scoped 属性(作用域)和 lang 属性的介绍