vue3中deep无法穿透根目录组件样式问题(上)

365 阅读2分钟

为什么要使用deep穿透样式?

  • 场景: 使用深度穿透样式的场景是在使用第三方UI库时,需要对组件的样式进行自定义,特别是对子组件的样式进行修改(一般在封装组件比较常见)。
  • 问题: 可vue为了组件直接的样式不被混淆,开发这可以使用scoped进行样式隔离。

scoped 是标记当前style标签需要样式隔离,vue在编译的时候会给该组件新增样式属性例如:

编译前

<div class="box">
  <el-button>按钮</el-button>
</div>
<style>
  .box{
    width:100px;
    height:100px;
    background-color: white;
  }
</style>

编译后

<div data-v-2fbe7ef>
  <el-button data-v-85a00ffn>按钮</el-button>
</div>
<style>
  .box[data-v-2fbe7ef]{
    width:100px;
    height:100px;
    background-color: white;
  }
</style>
  • 在CSS中,我们可以使用属性选择器([attribute])来选择具有特定属性的元素,并对其进行样式设置。
  • 在Vue中,当我们使用scoped样式时,编译后的Vue会为每个元素添加一个唯一的属性,并通过该属性来指定样式,这种做法的好处是可以实现样式的隔离,确保每个组件的样式只作用于当前组件,避免样式冲突的问题。

deep为什么能解决问题?

深度样式穿透(deep)能够解决样式作用范围扩展的问题,其原理是通过编译器将选择器转换为特定的选择器,从而实现样式的作用范围扩展。当使用深度选择器时,编译器会生成对应的特定选择器,使得样式只作用于指定的元素,而不受其他元素样式属性的影响。

深度样式穿透的原理是略过属性查找,即使Vue生成了元素样式属性,也不会影响这个单独的样式穿透。这样可以确保样式只作用于指定的元素,而不会被其他元素的样式所干扰。通过使用深度样式穿透,我们可以更精确地控制样式的作用范围,提高代码的可维护性和可读性。

<div class="box">
  <el-button>按钮</el-button>
</div>
<style>
  ::v-deep(.box){
    width:100px;
    height:100px;
    background-color: white;
  }
</style>

deep的多种实现方式

<div class="box">
  <el-button>按钮</el-button>
</div>
<style>
  >>> .box{}
  /deep/.box{}
  ::v-deep(.box){}
</style>

三种方式的原理相同,都是通过跳过属性查找来实现样式穿透。不同之处在于,Vue 2之前使用的是>>>或/deep/,而Vue 3废弃了这种方式,改为使用::v-deep来实现样式穿透。这样可以减少样式穿透的代码量,提高代码的可读性和维护性。