前言:vue+elementUI项目开发中,经常遇到修改elementUI组件样式无效的问题,
原因:在vue组件中我们经常需要给style添加scoped来使得当前样式只作用于当前组件的节点。添加scoped之后,工作原理是将当前组件的节点添加一个像”data-v-fae5bece”这样唯一属性的标识,这样就可以使得当前样式只作用于当前组件的节点。效果如下
测试项目结构是Home组件包含MiddleContainer组件、leftCharts层和rightCharts层,如下
如果各个嵌套的父子组件都使用scoped作用域拥有了有各自的唯一标识,类似于组件样式相互独立了,那么一般情况下,在父组件<style scoped>内样式不能设置子组件的节点elementUI样式,同样子组件<style scoped>内样式不能设置子父组件的节点的elementUI样式,所以产生修改elementUI组件样式无效的问题。
解决方式:
方法一:在app.vue根节点上修改样式进行全局覆盖
局部子组件MiddleContainer.vue如下
<template><div class="MiddleContainerPage"><p>这里是middleContainer 组件页面</p><div class="test"><a href="#">测试</a></div><el-button type="primary">测试在app.vue根组件上修改的效果</el-button></div>
</template><style lang="scss" scoped>.MiddleContainerPage {color:green;font-size: 2rem;.el-button--primary{color:orange;}}
</style>
app.vue组件如下
<style lang="scss">
#app {font-family: 'Avenir', Helvetica, Arial, sans-serif;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;text-align: center;width:100%;height:100%;color:#fff;.MiddleContainerPage .el-button--primary {color:red;}}
</style>
注意: <style lang="scss">不包含scoped
App.vue是项目的主/根组件,所有页面都是在App.vue下进行切换的。其实你也可以理解为所有的路由组件也是App.vue的子组件。这里测试发现 修改app.vue根节点的样式可以覆盖使用了scoped的子组件样式。也就是app.vue的样式等级高于使用了scoped的子组件样式等级。
方法二:去除局部/子组件scoped的style属性
该方法是去除局部/子组件的scoped作用域属性, 并定义一个类名或者Id来增加当前组件的命名空间,使当前<style >样式实现类似<style scoped >划分组件块的效果,达到不影响组件样式的目的。所以项目开发中会习惯为每一个组件的根节点添加一个类名或者Id来声明当前组件的命名空间,如下的class=“MiddlerContainerPage”
<template><div class="MiddleContainerPage"><p>这里是middleContainer 组件页面</p><div class="test"><a href="#">测试</a></div><el-button type="primary">测试在app.vue根组件上修改的效果</el-button></div>
</template><style lang="scss">.MiddleContainerPage {color:green;font-size: 2rem;.el-button--primary{color:orange;}}
</style><style>.MiddleContainerPage .el-button--primary{color:red;}
</style>
<style scoped >中使用深度选择器影响子组件
在<style scoped >样式中使用深度选择器影响子组件,可以使用 >>> 操作符,使用如下
.MiddleContainerPage >>>.el-button--primary{color:red;}
在 SCSS / Sass 之类的预处理器无法正确解析 >>>, 所以 /deep/ 操作符取而代之,代码如下
.MiddleContainerPage /deep/.el-button--primary{color:red;}
注意事项:
CSS 作用域不能代替 class。考虑到浏览器渲染各种 CSS 选择器的方式,当 p { color: red } 设置了作用域时 (即与特性选择器组合使用时) 会慢很多倍。如果你使用 class 或者 id 取而代之,比如 .example { color: red },性能影响就会消除。你可以在这块试验田中测试它们的不同。
在递归组件中小心使用后代选择器! 对选择器 .a .b 中的 CSS 规则来说,如果匹配 .a 的元素包含一个递归子组件,则所有的子组件中的 .b 都将被这个规则匹配。
参考网址:https://blog.csdn.net/xiazeqiang2018/article/details/81190275