不同预处理器less、scss等下如何写样式穿透

7,056 阅读1分钟
「这是我参与11月更文挑战的第8天,活动详情查看:2021最后一次更文挑战

为什么会需要样式穿透?

在Vue项目中,当我们引入第三方组件库时(如使用element-ui),需要在局部组件中修改第三方组件库样式,而又不想去除scoped属性造成组件之间的样式覆盖。这时候我们就需要样式穿透来实现我们想要的效果。

为什么要用scoped?

" 在vue组件中,在style标签上添加scoped属性,以表示它的样式作用于当下的模块,很好的实现了样式私有化的目的,这是一个非常好的机制。"

//button.vue
<template>
    <div class="button-warp">
        <button class="button">text</button>
    </div>
</template>
...
<style scoped>
    .button-warp{
        display:inline-block;
    }
    .button{
        padding: 5px 10px;
        font-size: 12px;
        border-radus: 2px;
    }
</style>

览器渲染出的html和css分别为:

<div data-v-2311c06a class="button-warp">
  <button data-v-2311c06a class="button">text</button>
</div>
.button-warp[data-v-2311c06a]{
  display:inline-block;
}
.button[data-v-2311c06a]{
  padding: 5px 10px;
  font-size: 12px;
  border-radus: 2px;
}

给HTML的DOM节点加一个不重复data属性(形如:data-v-2311c06a)来表示他的唯一性; 在每句css选择器的末尾(编译后的生成的css语句)加一个当前组件的data属性选择器(如[data-v-2311c06a])来私有化样式

实现样式穿透有几种方法呢?

通过上面scoped原理我们可以知道1个简单粗暴的方式就是去掉scoped

在scoped的情况下实现样式穿透:

  1. >>> 只作用于 css
<style scoped>
外层 >>> 第三方组件 {
  \样式\
}
</style>
  1. ::v-deep 只作用于 sass
<style lang="scss" scoped>
外层 ::v-deep 第三方组件 {
  \样式\
}
</style>
  1. /deep/ 只作用于 less
<style lang="less" scoped>
外层 /deep/ 第三方组件 {
  \样式\
}
</style>

具体代码示例如下:

// scss中编写
<style lang="scss" scoped>
.outer ::v-deep .inner{
    padding:0 10px;
}
</style>

//less中编写
<style lang="less" scoped>
.outer /deep/ .inner{
    padding:0 10px;
}
</style>

//style中编写
<style>
.outer {
    width: 90px;
    margin-top: 15px;
    >>> .inner {
      text-align: center!important;
    }
}
</style>