在Vue项目里使用Element UI的el-input时,很多同学希望输入框被选中(聚焦)时显示特定的背景颜色,而不是框架自带的浅蓝。要实现这个效果,需要先理解el-input的DOM结构和样式优先级,再通过动态绑定的方式把颜色控权交给Vue实例。

一、el-input的样式结构原理
el-input并不是一个单纯的input标签,它外层包裹了div.el-input,里面才是原生input或textarea。当输入框聚焦时,浏览器会给内部input加上:focus伪类,同时Element UI自身也通过CSS设置了背景和边框。如果我们直接在el-input上写style背景,实际作用的是外层容器,内部input仍用默认背景,所以肉眼看不出变化。
这意味着,要动态改选中背景,核心目标是影响input:focus或.el-input.is-focus状态下的背景属性。Vue层面我们只负责把颜色值传递进去,具体覆盖动作由CSS完成。搞清楚这一点,后面几种方案都不会迷路。
1.1 为什么普通class不生效
写过类似下面代码的人可能发现没反应:
<el-input class="my-input" :style="{ backgroundColor: focusColor }"></el-input>
这是因为backgroundColor被加到外层div,而用户看到的是里面input的白底。必须让样式穿透到内部元素,或者使用Element提供的变量机制。
二、方案:动态class配合深度选择器
这是最直接也最容易理解的做法。我们在Vue组件中维护一个表示颜色的变量,通过:class绑定一个状态类,再用/deep/或::v-deep覆盖内部input的背景。
2.1 基础实现代码
下面是单文件组件中的完整示例,focusColor由父级或接口动态改变,从而实现不同场景不同高亮色:
<template>
<div>
<el-input
v-model="text"
:class="{ 'custom-focus': true }"
@focus="onFocus"
@blur="onBlur">
</el-input>
</div>
</template>
<script>
export default {
data() {
return {
text: '',
focusColor: '#fff7e6'
}
},
methods: {
onFocus() {
// 可在此动态修改focusColor
this.focusColor = '#e6f7ff'
},
onBlur() {
this.focusColor = '#fff7e6'
}
}
}
</script>
<style scoped>
.custom-focus /deep/ .el-input__inner:focus {
background-color: v-bind(focusColor);
}
</style>
上面用了Vue3的v-bind in style特性,如果是Vue2可改用CSS变量。该方案优点是逻辑清晰,哪里聚焦改哪里;缺点是scoped样式需深度选择器,维护时要知道Element类名。
2.2 使用CSS变量兼容Vue2
Vue2不支持v-bind直接写样式,我们可以用CSS变量中转:
<template>
<el-input
:style="{ '--focus-bg': focusColor }"
class="var-input">
</el-input>
</template>
<style scoped>
.var-input /deep/ .el-input__inner:focus {
background-color: var(--focus-bg);
}
</style>
这样focusColor在data里更新,输入框聚焦背景就跟着变,不需要重新加载组件。
三、方案:通过CSS变量全局控制
如果整个项目有多个el-input需要统一切换主题色,可以在根节点设置CSS变量,el-input样式里读取它。这种方式适合暗黑模式或租户换肤。
3.1 全局变量定义
在App.vue或入口样式中:
:root {
--el-input-focus-bg: #f0f9eb;
}
然后在组件里覆盖:
.el-input__inner:focus {
background-color: var(--el-input-focus-bg) !important;
}
动态改变时只用document.documentElement.style.setProperty('--el-input-focus-bg', newColor)。好处是一次修改全站生效,但需要注意!important避免被Element默认样式压住。
四、方案对比与建议
我们把三种常见做法放一起看看差异:
| 方案 | 适用场景 | 维护成本 |
|---|---|---|
| 动态class+深度选择器 | 单个或少数输入框定制 | 低,逻辑直观 |
| CSS变量+Vue绑定 | Vue2项目局部动态色 | 中,需理解变量传递 |
| 全局CSS变量 | 多页面主题切换 | 低,但需注意权重 |
实际开发中,如果只改一两个表单,推荐第二种局部变量法;如果是中台系统换肤,用全局变量最省事。无论哪种,都不要试图直接改el-input标签上的style背景,那只会改到外层容器。
五、常见误区提醒
有人会用document.querySelector去拿input改背景,这在Vue里非常不可取,会脱离响应式体系,且组件销毁时容易留脏样式。也不要用inline style强行写内部input,因为el-input每次渲染都可能重置。
正确思路:让Vue管数据,让CSS管样式,两者通过class或CSS变量桥接。
只要记住el-input的真实背景在.el-input__inner上,动态改变选中背景就是一件很轻松的事。