需求:我要统一的校验效果

284 阅读1分钟

这是我参与11月更文挑战的第1天,活动详情查看:2021最后一次更文挑战

需求描述

开发基于 elementUI 2.15
用户在页面上一顿操作,表达了一堆信息要提交的时候,往往需要对用户数据做校验,提醒用户漏填或者输入不符合业务逻辑的数据。
如果是 el-input 之类的基础表单,老老实实基于 el-form 文档做文章就完了。那如果老板给了个不是 element 表单结构的内容要你做校验,那要怎么处理呢?
举个例子比如下面这种:

v1.gif

实现

直接用 message
this.$message({ message: '警告哦,这是一条警告消息', type: 'warning' });

没啥好说的,简单快捷!但缺点是用户可能并不知道到底哪没写对。

转换成 form

其实还是可以借助 el-form 的校验去做。
基本思路:

  1. 自定义规则里写该属性校验逻辑

  2. 该属性变更时(单独监听属性或者该属性变更事件),手动触发校验
    即: this.$refs.表单.validateField('属性', (e) => { // 回调 })

  3. 属性 error 后对应的样式变更(红框框出来告知用户哪里不对)
    期间也尝试了用 show-message 配合 error 去做,也能实现。但会把处理表单数据的逻辑和校验逻辑混合到一起,个人更倾向于现在实现的思路。

整理代码如下
<el-form :model="form" :rules="rules" ref="ruleForm">
      <el-form-item prop="group" label-width="0px" class="custom-form-item">
        <li
          v-for="(item, index) in form.group"
          :key="`${item.name}--${index}`"
          class="group-item"
        >
          <span>{{ item.name }} -- {{ index }}</span>
          <i
            v-if="item.type !== '0'"
            @click="del(index)"
            class="el-icon-delete"
          ></i>
        </li>
      </el-form-item>
    </el-form>
data() {
    const controlGroup = {
      name: '对照组',
      type: '0'
    }
    const experimentalGroup = {
      name: '实验组',
      type: '1'
    }
    var validatePass = (rule, value, callback) => {
      const maxN = 4
      const minN = 1
      if (value.length - 1 > maxN) {
        callback(new Error(`实验组最多${maxN}个`))
      } else if (value.length - 1 < minN) {
        callback(new Error(`实验组最少${minN}个`))
      } else {
        callback()
      }
    }
    return {
      form: {
        group: [controlGroup]
      },
      rules: {
        group: [{ validator: validatePass, trigger: 'change' }]
      },
      baseAddGroup: experimentalGroup
    }
  },
  watch: {
    'form.group'() {
      this.$refs.ruleForm.validateField('group', (e) => {})
    }
  },
  methods: {
    addExperimentalGroup() {
      this.form.group.push(this.baseAddGroup)
    },
    del(i) {
      this.form.group.splice(i, 1)
    }
  },
/deep/ .custom-form-item.el-form-item.is-error .el-form-item__content {
  border: 1px solid #ff3b34;
  border-radius: 4px;
  box-sizing: border-box;
}

完成!!