记录一次ElementUI踩坑艰辛历程

1,474 阅读4分钟

记录一次ElementUI踩坑艰辛历程

最近在工作上遇到了一个需求,具体如下

image-20231104133840811

如果所示:

有一个Select和一个Input这两个组件要组合到一起

我看到这个需求的表情

841d04523e41b9c0f4c99cb58d4b36a2.jpg

这不是挺简单的吗??? 要知道熟悉ElementUI的朋友们,就知道Input其实就有这个功能

image-20231104134350628

在官方的组件库中,就已经提供了实例,而且很简单so easy

但是事与愿违,我这里先抛开原有框架的封装的问题,先来研究一下ElementUI对于这个组件有什么问题?

我们可以看到一个比较特别点是上面图中证件类型和证件号这两个字段,都是必填的,我这里写了一个简单demo

界面如下:

一个带Select的Input的框,然后点击立即创建,校验表单,然后提交

image-20231104135115023

正常情况下,操作没有问题

30

那么假设不输入直接选择立即创建

31

这时候可以看到,明显Select,没有去校验,问题出在哪里?

接着我们去分析一下代码

    <el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="150px" class="demo-ruleForm">
      <el-form-item label="测试复杂输入框" prop="testInput">
        <el-input placeholder="请输入内容" class="input-with-select" v-model="ruleForm.testInput">
          <el-select style="width: 200px;" v-model="ruleForm.select" clearable slot="prepend" placeholder="请选择">
            <el-option label="餐厅名" value="1"></el-option>
            <el-option label="订单号" value="2"></el-option>
            <el-option label="用户电话" value="3"></el-option>
          </el-select>
          <el-button slot="append" icon="el-icon-search"></el-button>
        </el-input>
      </el-form-item>
      <el-form-item>
          <el-button type="primary" @click="submitForm('ruleForm')">立即创建</el-button>
          <el-button @click="resetForm('ruleForm')">重置</el-button>
      </el-form-item>
    </el-form>

校验规则如下:

        rules: {
          testInput: [
            { required: true, message: '请输入内容', trigger: 'blur' }
          ],
        }

那么这时候我们就会发现,其实rule仅仅只是对input进行校验,没有对select进行校验,那么我们就要针对select进行校验

我这时候新增了select校验规则

        rules: {
          testInput: [
            { required: true, message: '请输入内容', trigger: 'blur' }
          ],
          select: [
            { required: true, message: '请选择select', trigger: 'change' }
          ],
        }

但是这样肯定是不够的,要知道form是去根据formItem上的prop进行校验的,所以还需要对元素进行修改,这里对原本select外加了一层form-item并且绑定上了prop

<el-input placeholder="请输入内容" class="input-with-select" v-model="ruleForm.testInput">
    <el-form-item prop="select" slot="prepend">
        <el-select style="width: 200px;" v-model="ruleForm.select" clearable placeholder="请选择">
            <el-option label="餐厅名" value="1"></el-option>
            <el-option label="订单号" value="2"></el-option>
            <el-option label="用户电话" value="3"></el-option>
        </el-select>
    <el-button slot="append" icon="el-icon-search"></el-button>
    </el-form-item>
</el-input>

那么这时候我们再去看一下效果

image-20231104142151706

似乎进行校验了,但是有明显的两个问题

  1. 提示的文字重叠了
  2. select框还是没有红色的边框

先处理第一个问题

image-20231104142819722

从图中我们看出两个FormItem的内容区域重叠了,而提示语默认是在formItem顶部进行插入

那么这时候我们去看html的结构

image-20231104143539668

可以看到两个错误替换的html提示层级不同,那么这时候就好办了

通过修改框架css就可以实现我们需要的效果了,这里我们分别对外层和内容的提示进行了样式修改

::v-deep .el-form-item {
  .el-form-item__error {
    left: 200px;
  }
  .el-input-group__prepend {
    // 内层的样式 我们需要恢复原貌
    .el-form-item__error {
      left: 0px;
    }
  }
}

最后得到的效果如下:

image-20231104144244752

是不是很完美,但是这时候还得注意一种情况,我这里只有一个formItem,如果有多个呢

image-20231104144459105

显示这时候还会出现问题我们需要限定的样式只是特定的FormItem我们给自己的formItem加一个特定的class

image-20231104144943731

最后效果如下,这样我们提示语错乱重叠的问题就处理好了

这效果显然还不是最终的效果,还有红框的问题没有解决

image-20231104150002867

通过html元素上分析,发现到如果是未填的表单中有一个isErrorclass,那么我们就可以通过这个class进行对select框的选取

image-20231104145837687

最后修改后的效果,完成符合我们的需求

image-20231104150038356

闲谈

不得不说,处处是坑啊,原以为一个简单需求,最后实现起来这么多问题,笔者心里苦,感觉工作上经常遇到这种问题,看似简单的问题,里面牵扯到许多的东西。

虽然各位在此看起来可能比较简单,但是如果放在一个复杂的组件中呢。

image-20231104153945549

一个组件修改差点要了一条老命

85955792dfd00903397ba96d12af53ae.jpeg

不过幸好最后还是艰难的做出来了。