目录
存在问题
为何修改修改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 样式
.appContent {
.el-input {
width: 200px;
.el-input__inner {
border-color: red;
}
}
}
打开浏览器,查看控制台,样式如下:
修改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标签,如下
.appContent {
.el-input__inner {
border-color: red;
}
}
为了避免样式污染,可以在需要修改的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。
深度选择器的工作原理,如下样式代码:
.a >>> .b { /* ... */ }
将会编译成:
.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样式
type="textarea" :rows="4" placeholder="最多输入200字" v-model="ele.value" maxlength="200" resize="none" show-word-limit :autosize="{ minRows: 4, maxRows: 8 }">
// /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框架的样式类之前的,因为写在自定义类名之前有的时候是不会生效的。