Vue的样式穿透(在父组件中为子组件定义样式)
在使用Vue开发前端项目时,我们经常需要引入第三方组件,比如下面的例子(假设我们已经注册了element-ui):
<template>
<div class="root">
<el-button type="plain">点击我</el-button>
</div>
</template>
这是一个来自element-ui的按钮组件,它会渲染成这样:
那我如果我们想修改这个第三方组件的样式该怎么办呢?
下面的样式并不会生效:
<style scoped>
.root .el-button--plain {
font-weight: bold;
}
</style>
因为el-button--plain
对应的标签并不在当前组件作用域内,它在子组件<el-button>
的作用域内。
一种非常不优雅的方案是,去掉style的scoped属性,比如:
<style>
.root .el-button--plain {
font-weight: bold;
}
</style>
至于el-button--plain
这个类名,需要打开浏览器开发者工具,从element面板中查看。
说到这里,我们需要先了解一下为什么Vue的组件样式推荐添加scoped属性。
我们知道,普通的样式标签内定义的样式对整个页面都是有效的。因此,假如两个组件内存在具有相同类名的标签,那么当我们为其中一个定义样式时,另一个标签的样式也会受到影响(这种影响大多数时候是不利的,因为这种影响不可控)。为了解决这个问题,我们可以在样式标签上添加scoped
属性,这样,这个标签内定义的样式只在当前组件内有效。scoped的实现机制为,webpack会在打包时给每个组件的所有标签添加一个特定的属性,如:
然后,添加了scoped属性的标签内的所有css选择器都会带上这个属性,因此,对于下面的样式:
编译之后可能是这样的:
由于只有当前组件内的标签才会携带data-v-752ada3f
属性,所以这条样式只会对当前组件内的标签生效。这样就可以保证这条样式只对当前组件内的标签有效。
所以,一旦去掉scoped属性,我们就又回到了原本的问题中。那么如何优雅地解决这个问题呢?
其实可以这样(这里collapse-title
是组件内定义的类名,而el-collapse-item__header
是组件引用的第三方组件内定义的):
这里是没有使用css预编译器的写法,>>>
表示要穿透组件,使该样式对其子组件生效。它编译后是这样的:
可以看到,现在只有根选择器带了属性限制,三大于号后面的选择器则没有,这样,el-collapse-item__header
就不限制必须属于当前组件了,于是这条属性对子组件内的标签就可以生效了。并且由于scoped属性的存在,这条样式不会影响到其他外部组件(不过如果当前组件的子组件也引用了第三方组件时需要慎重,因为它会继续穿透子组件)。
如果使用了css预编译器,如scss,则需要使用下面的语法:
这里的/deep/
表示这个选择器不属于当前组件,而是属于其子组件,同样可以达到穿透组件修改第三方组件样式的效果。
本文地址:https://blog.csdn.net/qq_41694291/article/details/107498335
推荐阅读
-
vue slot 在子组件中显示父组件传递的模板
-
vue开发中,父组件添加scoped之后 如何解决在父组件中无法修改子组件样式的问题?
-
vue里面父组件修改子组件样式的方法
-
vue封装element组件库中的封装通用table,是否启用多选、按钮及是否分页,样式可自定义设置
-
vue中在父组件点击按钮触发子组件的事件
-
Vue的样式穿透(在父组件中为子组件定义样式)
-
vue项目css中修改子组件样式又不会造成全局污染的方法
-
如何修改Vue.js中scoped模式下的子组件内部标签样式
-
VUE 中的scoped 及穿透方法(修改第三方组件的局部样式)
-
vue slot 在子组件中显示父组件传递的模板