我们使用很多 vue 的组件库(element-plus、vant),在修改样式的时候需要进行其他操作才能成功更改样式,此时就用到了样式穿透。
而不能正常更改样式的原因就是 scoped 标记。
scoped 的渲染规则:
<template>
<main>
<el-input
placeholder="请输入"
class="ipt"
></el-input>
</main>
</template>
<script setup lang="ts">
</script>
<style scoped lang="less">
.ipt {
width: 300px;
margin: 100px 400px;
}
</style>
-
给 HTML 的 DOM 节点增加一个不重复的 data 属性,表示它的唯一值。
-
编译后的生成的 css 语句,在每句 css 选择器的末尾加一个当前组件的 data 属性选择器来私有化样式。
-
如果组件内部包含有其他组件,只会给其他组件的最外层标签加上当前组件的 data 属性。
此时 App 组件里面包含了 el-input 组件。
这时我们给 input 框加一个背景样式:
.ipt {
width: 300px;
margin: 100px 400px;
.el-input__inner {
background: tomato;
}
}
此时 scoped 的第二条和第三条之间的矛盾就出现了。
.el-input__inner 里面并没有 data-v-7a7a37b1 属性,导致背景样式失效。
样式穿透解决这个问题:
-
如果是 Vue2:
.ipt { width: 300px; margin: 100px 400px; /deep/ .el-input__inner { background: tomato; } }
-
如果是 Vue3:
.ipt { width: 300px; margin: 100px 400px; :deep(.el-input__inner) { background: tomato; } }
问题解决!