Vue 中动态与静态处理 Element UI/Element Plus 组件禁用状态样式

发布于:2024-05-10 ⋅ 阅读:(26) ⋅ 点赞:(0)

本文主要探讨在 Vue.js 项目中,特别是搭配 Element UI 或 Element Plus 组件库时,如何灵活处理 el-inputel-select 组件禁用状态下的字体颜色问题。我们将详细分析如何使用 CSS 选择器穿透(如 ::v-deep)来改变禁用状态下的输入框字体颜色,并探讨通过 JavaScript 动态添加样式的可能性及其局限性。

一、静态样式修改 - 使用 ::v-deep 穿透组件样式

在 Element UI 或 Element Plus 中,当我们给 el-inputel-select 添加 :disabled="true" 属性时,其字体颜色会变为暗色以表示禁用状态。

在这里插入图片描述

若要将禁用状态下的字体颜色更改为红色,可以通过 CSS 选择器穿透来实现:

/* Vue 2.x + Element UI */
.el-input.is-disabled /deep/ .el-input__inner,
.el-select.is-disabled /deep/ .el-input__inner {
  color: red !important;
}

/* Vue 3.x + Element Plus */
.el-input.is-disabled ::v-deep .el-input__inner,
.el-select.is-disabled ::v-deep .el-input__inner {
  color: red !important;
}

在这里插入图片描述

但这里,::v-deep/deep/(Vue 2.x)选择器可以帮助我们穿透组件的作用域,修改内部 el-input__inner 元素的颜色。这只有 el-input 内部包裹的 el-input,其禁用状态的字体颜色能成功更改为红色,而 el-select 不行 。需要将::v-deep/deep/提前。

/* Vue 2.x + Element UI */
 /deep/ .el-input.is-disabled.el-input__inner,
.el-select.is-disabled /deep/ .el-input__inner {
  color: red !important;
}

/* Vue 3.x + Element Plus */
::v-deep .el-input.is-disabled  .el-input__inner,
.el-select.is-disabled ::v-deep .el-input__inner {
  color: red !important;
}

在这里插入图片描述

二、选择器的优先级和匹配顺序

在 Vue SFC 的 scoped CSS 中,.el-input.is-disabled ::v-deep .el-input__inner::v-deep .el-input.is-disabled .el-input__inner 在意图上都是为了穿透组件样式作用域来修改内部元素 .el-input__inner 的样式,尤其是当 .el-input 处于禁用状态(.is-disabled 类名存在)时。

区别在于选择器的优先级和匹配顺序:

  1. .el-input.is-disabled ::v-deep .el-input__inner
    这种写法先指定了 .el-input.is-disabled 这个类选择器,然后才使用 ::v-deep 进行穿透。这意味着它首先会找到所有带有 .el-input.is-disabled 类的元素,然后再尝试穿透这些元素去影响内部 .el-input__inner 的样式。

  2. ::v-deep .el-input.is-disabled .el-input__inner
    这种写法先使用 ::v-deep 进行穿透,然后指定了类选择器 .el-input.is-disabled .el-input__inner。尽管两者最终都旨在达到相同的目的,但逻辑上这种写法似乎是试图穿透任意层次以查找满足 .el-input.is-disabled .el-input__inner 这一组合条件的所有元素。

三、动态添加样式 - 使用 Vue 实例属性(非推荐)

尽管 Vue 提供了多种方式动态添加样式,但直接通过 JavaScript 修改类似 ::v-deep 规则的样式并不推荐,尤其对于穿透子组件样式的情况。不过,这里仍提供一种使用 Vue 实例 $style 属性(仅限 Vue 2.x)的示例,以说明其工作原理:

// 在 Vue 组件中
export default {
  data() {
    return {
      dynamicStyle: {}
    };
  },
  created() {
    this.updateDynamicStyle();
  },
  methods: {
    updateDynamicStyle() {
      // 创建模拟 CSS 样式对象(但这并不能应用于穿透子组件)
      const styleObject = {
        '.el-input.is-disabled .el-input__inner': {
          color: 'red !important' // 注意这里没有使用 ::v-deep,因为 $style 不支持穿透
        }
      };

      // 合并到组件的 $style 属性
      this.dynamicStyle = Object.assign({}, this.dynamicStyle, styleObject);
    }
  }
};

然后在模板中引用:

<div :style="dynamicStyle">
  <!-- el-input 和 el-select 等组件 -->
</div>

四、区别总结

  • ::v-deep/deep/ 选择器是在 CSS 中穿透组件作用域修改子组件样式的一种手段,特别适用于 Element UI 和 Element Plus 组件库。
  • 动态添加样式(如通过 $style)适用于在运行时调整组件实例自身的样式,但不适用于穿透到子组件的样式。

五、应用场景总结

在实际项目开发中,推荐采用 ::v-deep 穿透组件样式的方式来定制 Element UI/Element Plus 组件的禁用状态样式,这种方式更为直观、稳定且易于维护。对于动态添加样式的需求,优先考虑使用 Vue 的响应式数据绑定至 :style 特性来调整组件本身的样式,而非穿透到子组件。在 Vue 3.x 中,官方已不再推荐使用 $style,改用 <style> 标签结合 scoped 或 CSS 变量等方式进行样式管理。


网站公告

今日签到

点亮在社区的每一天
去签到