Vue3中scoped样式穿透原理以及如果使用样式穿透

主要是用于修改很多vue常用的组件库(element, vant, AntDesigin),虽然配好了样式但是还是需要更改其他的样式,就需要用到样式穿透。

scoped的原理

vue中的scoped 通过在DOM结构以及css样式上加唯一不重复的标记:data-v-hash的方式,以保证唯一(而这个工作是由过PostCSS转译实现的),达到样式私有化模块化的目的。

总结一下scoped三条渲染规则

1.给HTML的DOM节点加一个不重复data属性(形如:data-v-123)来表示他的唯一性。
2.在每句css选择器的末尾(编译后的生成的css语句)加一个当前组件的data属性选择器(如[data-v-123])来私有化样式。
3.如果组件内部包含有其他组件,只会给其他组件的最外层标签加上当前组件的data属性。


PostCSS会给一个组件中的所有dom添加了一个独一无二的动态属性data-v-xxxx,然后,给CSS选择器额外添加一个对应的属性选择器来选择该组件中dom,这种做法使得样式只作用于含有该属性的dom——组件内部dom, 从而达到了'样式模块化'的效果。

使用elementUi来做一个例子

在vue组件中引入一个el-input标签,然后给它添加相应的样式,看一下页面上的变化

vue组件代码:

<template>
  <div>
    <el-input v-model="input" placeholder="Please input"  class="username"/>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
const input = ref('')
</script>

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

在页面上渲染后的结果:可以明显看到class后面加上了属性选择器 

我们试着通过el-input__inner给输入框内部的input元素改变一下背景颜色: 

发现页面上并没有生效:追究原因,原来是在el-input__inner上也添加了属性选择器,这就是scope属性引起的scope特征第二条和第三条冲突了,所以.el-input__inner[data-v-7a7a37b1]找不到对应的元素

 

解决scoped样式穿透

第一种解决办法

最简单的解决办法就是去掉scoped属性:

这样就生效了:但是这可能就会引起样式冲突,导致其他页面上的组件样式也会改变

第二种解决办法

使用样式穿透,在vue2中可以使用/deep/ .el-input__inner 这种方式,在vue3中需要使用:deep(.el-input__inner)这种方式:

这样修改之后,真正的样式选择器就会改变为:所以就能成功选择到对应的标签

猜你喜欢

转载自blog.csdn.net/weixin_44786530/article/details/130842003