vue中scoped的样式污染处理

1.为什么要用scoped? 

当组件间的类名相同时,会发生css样式污染问题。

如果是父子组件有相同类名,则样式都为父组件中的同类名样式,如果是兄弟组件,看哪个组件最后创建,样式就以哪个为主进行覆盖之前创建的组件的样式。

//父组件中div的样式
<template>
  <div class="box"></div>
  <Child/>
</template>

<script>
  import Child from './components/Child.vue'
  export default {
    components: {
      Child,
    }
  }
</script>

<style>
  .box {
    background-color: red;
    height: 200px;
    width: 200px;
  }
</style>


//子组件中div的样式
<template>
  <div class="child"></div>
</template>

<style>
  .child {
    width: 500px;
    height: 500px;
    background-color: black;
  }
</style>

//兄弟组件1
<template>
  <div class="child"></div>
</template>

<style>
  .child {
    width: 500px;
    height: 500px;
    background-color: black;
  }
</style>

//兄弟组件2(后创建)
<template>
  <div class="child"></div>
</template>

<style>
  .child {
    width: 10px;
    height: 10px;
  }
</style>

 从上面的图中,可以清晰的看到,父子组件只生效父组件的样式,子组件的样式不起作用了,兄弟组件后创建的样式会替换先创建的,这就是没有scoped产生的css样式污染,当给style标签加上scoped属性时就不会产生这种问题了。

 2.​scoped原理

当设置了scoped属性时,style里的样式仅作用于当前组件,便不会产生组件间的样式污染。

1.给组件中的样式对应的标签设置一个标签属性[data-v-hash字符串](形如:<div class="child" data-v-45972626=""></div>)

2.给css选择器的后面加上[data-v-hash字符串](形如:.child[data-v-45972626] {.....})来表示唯一性。

postcss转换 

//转化前
<template>
  <div class="child"></div>
</template>

<style scoped>
.child {
  width:200px;
  height:200px;
}
</style>

//转化后
<template>
  <div class="child" data-v-45972626></div>
</template>

<style scoped>
.child[data-v-45972626] {
  width:200px;
  height:200px;
}
</style>

注意:

  当父组件和子组件都有scoped时,父组件的data-v-hash会出现在父组件和子组件的data-v-hash后,从而再次引起样式污染(如下图,子组件再次样式失效)。

  或者引入第三方组件时,需要在组件内修改样式,如果遇到同样的类名,也会再次引起样式污染。

解决这个问题有两种方法:

  1. 可以在<style scoped></style> 标签后再多加一个<style></style>标签用来写没有data-v-hash的样式(也就是全局通用的样式),或者直接在<style scoped></style>标签里写 :global(选择器){...}。
  2. 使用样式穿透(深度选择):在需要去掉data-v-hash的选择器前面加上下面的格式即可去除样式污染
  • sass/less中使用'/deep/'或'::v-deep'或':deep(选择器){...}'
  • 非预编译中使用'>>>'

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值