vue知识点之css样式穿透

样式穿透:当我们在vue项目中引用到第三方组件时,比如element-ui,常常需要更改某些元素的样式,但如果使用常规的css样式覆盖的方式是经常无效的,那么我们就要用到“样式穿透”的方法。

一、使用scoped的原理是什么?

在一个组件中,我们定义组件样式一般写在页面的最下方,以style包裹
<style>
    .div {

    }
</style>

为了不污染全局样式,我们在style上加一个scoped修饰符,这个样式就只在当前组件的范围内有效

<style scoped>
    .div{
        
    }
</style>

但这是如何作到在当前组件范围内有效的呢?我们打开F12,查看一下元素的DOM结构就可以看出端倪:

 在每个dom元素上,有一个data-v-xxxxxxxx的标识符,这个标识符就是保证scoped有效的根本!我们定位到button上,查看css样式:

 

我们看到元素后面被加上了[data-v-xxxxxxxx]属性,这也就是CSS的属性选择器,只有拥有这个属性的元素或类才会应用此样式。每个组件下[data-v-xxxxxxxx]这个id值是一致的,所以限制了其作用范围。

清楚了这个原理之后,我们就可以解释为什么很多第三方组件引入进来,通过常规的css样式覆盖是无效的,因为该组件是scoped,父组件是触及不到其内部的样式的!

那我们要是必须要改变第三方组件的样式要怎么办呢?这里就要说“样式穿透”的方法了。

所谓样式穿透,就是在父级组件中强制去修改子级组件的内部样式,注意这里的父子层次并不一定是一级,可能是很多级。

具体要怎么作呢?按不同的css的渲染器写法也是不同的。

二、vue样式穿透

☘️  1.普通的css的样式穿透: 使用:(>>>)
!!!在要修改的样式前添加>>>符号,实际上>>> ::v-deep /deep/三者都可用
外层类 >>> 想要修改的类名 {
  要修改的样式
}
.wrapper >>> .el-card__header {
    border-bottom: none
}
☘️ 2. sass和less的样式穿透 使用:(/deep/)
!!!在要修改的样式前添加::v-deep ,/deep/也是可用的
外层类  /deep/  想要修改的类名 {
  要修改的样式
}
.wrapper /deep/ .el-card__header {
  border-bottom: none
}
☘️ 3. scss穿透 使用:(::v-deep)
!!!在要修改的样式前添加 ::v-deep ,实际上/deep/也可用,但是在vue3中可能会报错
::v-deep 想要修改的类名 {
  要修改的样式
}
::v-deep .el-card__header {
  border-bottom: none
}

三、在vue3中怎么使用:deep

如果你是使用vue2.7以上版本以及包括vue3::v-deep也会生效,但是会有警告,这是因为Vue 3 提供了更好的语法,推荐使用 :deep()。

☘️ 1. 基本用法:

当你的组件样式使用 scoped,你想要影响到子组件中的元素时,可以使用 :deep()。

<!--模版-->
<template>
  <div class="parent">
    <ChildComponent />
  </div>
</template>
  
<!--样式-->
<style scoped>
/* 作用于 ChildComponent 内部的某个元素 */
:deep(.child-element) {
  color: red;
}
</style>
☘️ 2. 嵌套用法:

你可以将 :deep() 作为一个选择器的一部分,或与其他选择器组合。

<style scoped>
/* 作用于子组件内部的 .child-element,并且父级是 .parent */
.parent :deep(.child-element) {
  color: red;
}
</style>

你也可以使用多个选择器:

你可以在多个嵌套的元素中使用 :deep()。

<style scoped>
.parent :deep(.child-element) :deep(.deep-child-element) {
  font-size: 18px;
}
</style>

!!!注意事项:

1. :deep() 只能在 scoped 样式中使用,如果你不使用 scoped,则不需要使用 :deep(),因为样式默认是全局的。
2. 如果你不想影响到子组件的样式,最好保持样式的封闭性,不使用 :deep()。
3. 这样可以确保你在 Vue 3 的 scoped 样式下,有选择性地影响子组件的内部元素。

四、总结

1. 如果你使用的是css,没有使用css预处理器,则可以使用>>>/deep/::v-deep

2. 如果你使用的是less或者node-sass,那么可以使用/deep/::v-deep都可以生效。

3. 如果你使用的是dart-sass,那么就不能使用/deep/,而是使用::v-deep才会生效。

⚠️但是如果你是使用vue2.7以上版本以及包括vue3::v-deep也会生效,但是会有警告

警告说的很清楚,::v-deep已经废弃,应该使用:deep()

!!!总的来说,::v-deep适应性更好,更多地使用。

posted on 2024-09-27 19:44  梁飞宇  阅读(1187)  评论(0)    收藏  举报