目录
存在问题
为何修改修改UI组件的样式会不生效
如何修改UI组件样式
1,去除style标签上的scoped属性
2,使用UI组件自带的custom-class属性
3,使用深度选择器
4,去除scoped元素的同时使用深度选择器 /deep/
存在问题
开发项目的时候一般会使用第三方UI框架,如elementUI、Vant,uni-ui,uView等,那么就存在一个比较棘手的问题,就是样式修改:
1,一般在修改UI框架自带的样式时有时很难生效
2,或者只是想要修改当前组件内UI组件的样式,而不影响全局
3,在style标签携带scoped元素的时候就很难覆盖UI框架的样式
为何修改修改UI组件的样式会不生效
~不关心原理可以跳过~
在编写vue组件代码的时候,为了避免样式污染,每个页面的 style 标签都会加上 scoped 属性,vue组件编译后,会将 template 中的每个元素加入 [data-v-xxxx] 属性来确保本组件的样式不会污染全局,这就是 scoped 属性的原理。
比如下面代码
// style 样式 <style lang="scss" scoped> .appContent { .el-input { width: 200px; .el-input__inner { border-color: red; } } } </style>
打开浏览器,查看控制台,样式如下:
修改elementUI input 组件的样式,如上面代码,
- 修改 el-input 的宽度,可以生效
- 修改 el-input__inner 的 border-color 无法生效
原因:
因为 data-v-xxx 属性只加在UI组件(子组件)的第一层,子组件中其他 DOM 元素是没有 data-v-xxx 这个属性的,而你写在 带有 scoped 属性的 style 标签中的样式编译后都会被添加 data-v-xxx 属性,样式只作用于有 data-v-xxx 这个属性的DOM,而真实的UI组件内部DOM元素上并没有被添加 data-v-xxx 属性,所以样式不会生效。
就比如 el-input__inner 的样式不会生效,那么可以使用深度选择器来修改。
如何修改UI组件样式
1,去除style标签上的scoped属性
vue中是允许写多个style标签的,所以可以重新定义一个不带scoped属性的style标签,如下
<style lang="scss">
.appContent {
.el-input__inner {
border-color: red;
}
}
</style>
为了避免样式污染,可以在需要修改的UI组件的外层添加自定义class等,向下包含UI组件的样式代码,这样可以防止影响到别的组件。
2,使用UI组件自带的custom-class属性
一些UI组件向外提供了接口,可以使用类似 custom-class 或者 custom-style 等的属性来修改UI组件的样式,具体使用根据UI框架不同,使用方式不同。
也可以参考第一条,定义 custom-class 类包裹UI组件类,修改样式。
3,使用深度选择器
深度选择器有多种写法,比如
- /deep/
- >>>
- ::v-deep
以上写法都是可以的,但是具体使用根据场景不同,写法不同。 一般情况,stylus的样式穿透 使用>>>, sass和less的样式穿透 使用/deep/,在vue3中可以会出现/deep/编译报错,可以使用::v-deep。
深度选择器的工作原理,如下样式代码:
<style scoped>
.a >>> .b { /* ... */ }
</style>
将会编译成:
.a[data-v-f3f3eg9] .b { /* ... */ }
修改VantUI中search组件的样式:
.van-search__content {
background: #ededed;
height: 0.5rem;
.van-cell.van-cell--borderless.van-field {
padding: 0;
line-height: inherit;
/deep/.van-field__left-icon {
.van-icon {
font-size: 0.35rem !important;
}
}
/deep/.van-field__value .van-field__body .van-field__control {
// 没有必要写多层deep 父类有deep后子类自动也会深度选择
color: red;
font-size: 0.2rem;
}
}
}
修改elementUI textarea样式
<div class="liForm">
<el-input
type="textarea"
:rows="4"
placeholder="最多输入200字"
v-model="ele.value"
maxlength="200"
resize="none"
show-word-limit
:autosize="{ minRows: 4, maxRows: 8 }">
</el-input>
</div>
// /deep/是需要写在UI框架的样式类之前的
.liForm {
/deep/.el-textarea {
.el-input__count {
bottom: 2px!important;
}
}
}
// 下面的方式不会生效**********
/deep/.liForm {
.el-textarea {
.el-input__count {
bottom: 2px!important;
}
}
}
4,去除scoped元素的同时使用深度选择器 /deep/
有的时候上面的所有方法你已经都试过了,但是还是不能修改UI组件的样式,那么你可以在不带 scoped 属性的 style 标签内修改。
- 为了防止样式污染,同样可以在外层添加自定义class,来包裹需要修改的UI框架元素,或者直接在框架元素上自定义class来包裹。
- /deep/(深度选择器)是需要写在UI框架的样式类之前的,因为写在自定义类名之前有的时候是不会生效的。