美文网首页
Element UI 校验form表单 升级版

Element UI 校验form表单 升级版

作者: jia林 | 来源:发表于2021-12-10 18:15 被阅读0次

    前言:业务中台系统中,有表单校验,一般我们都会配置rules属性,进行校验,如果存在多个表单校验,对用户体验很不友好。利用 scrollIntoView 可以快速定位到报错的表单项

    • 多个表单项校验图片


      image.png
    • 使用 scrollIntoView 改造后,就可以快速定位


      image.png

    实现方案

    1.scrollIntoView使用方法

    2.关键逻辑实现

    • 提交表单时,获取错误信息的集合
    • 循环错误信息的结合
    • 绑定点击事件,跳到对应的表单项
        // 获取错误信息
        getErrorInfo(formName) {
          const fields = this.$refs[formName].fields
          let errMap = []
          fields.forEach(item => {
            let obj = {}
            const { validateState, validateMessage, $options: { propsData }, } = item
            if (validateState === 'error') {
              obj.status = validateState
              obj.text = validateMessage
              obj.prop = propsData.prop
              obj.label = propsData.label
              errMap.push(obj)
            }
          })
          this.errMap = errMap
        },
    
        // 跳到对应的报错字段
        scrollToField(prop) {
          const labelNode = document.querySelector(`label[for="${prop}"]`)
          labelNode && labelNode.scrollIntoView(true)
        },
    

    3.z最终代码

    <template>
      <div>
        <el-card shadow="never" :body-style="{ padding: '0px' }">
          <el-form
            :model="ruleForm"
            :rules="rules"
            ref="ruleForm"
            label-width="100px"
            class="demo-ruleForm"
          >
            <el-form-item label="活动名称" prop="name">
              <el-input v-model="ruleForm.name"></el-input>
            </el-form-item>
            <el-form-item label="活动区域" prop="region">
              <el-select v-model="ruleForm.region" placeholder="请选择活动区域">
                <el-option label="区域一" value="shanghai"></el-option>
                <el-option label="区域二" value="beijing"></el-option>
              </el-select>
            </el-form-item>
            <el-form-item label="活动时间" required>
              <el-col :span="11">
                <el-form-item prop="date1">
                  <el-date-picker
                    type="date"
                    placeholder="选择日期"
                    v-model="ruleForm.date1"
                    style="width: 100%"
                  ></el-date-picker>
                </el-form-item>
              </el-col>
              <el-col class="line" :span="2">-</el-col>
              <el-col :span="11">
                <el-form-item prop="date2">
                  <el-time-picker
                    placeholder="选择时间"
                    v-model="ruleForm.date2"
                    style="width: 100%"
                  ></el-time-picker>
                </el-form-item>
              </el-col>
            </el-form-item>
            <el-form-item label="即时配送" prop="delivery">
              <el-switch v-model="ruleForm.delivery"></el-switch>
            </el-form-item>
            <el-form-item label="活动性质" prop="type">
              <el-checkbox-group v-model="ruleForm.type">
                <el-checkbox label="美食/餐厅线上活动" name="type"></el-checkbox>
                <el-checkbox label="地推活动" name="type"></el-checkbox>
                <el-checkbox label="线下主题活动" name="type"></el-checkbox>
                <el-checkbox label="单纯品牌曝光" name="type"></el-checkbox>
              </el-checkbox-group>
            </el-form-item>
            <el-form-item label="特殊资源" prop="resource">
              <el-radio-group v-model="ruleForm.resource">
                <el-radio label="线上品牌商赞助"></el-radio>
                <el-radio label="线下场地免费"></el-radio>
              </el-radio-group>
            </el-form-item>
            <el-form-item label="活动形式" prop="desc">
              <el-input type="textarea" v-model="ruleForm.desc"></el-input>
            </el-form-item>
          </el-form>
        </el-card>
        <div style="text-align: right">
          <el-popover placement="top" trigger="hover">
            <ul>
              <li
                @click="scrollToField(item.prop)"
                v-for="item of errMap"
                :key="item.prop"
                style="
                  border-bottom: 1px solid #ccc;
                  cursor: pointer;
                  padding: 10px 0;
                "
              >
                {{ item.text }}
              </li>
            </ul>
            <el-button slot="reference" type="text" style="color: red"
              >{{ errMap.length }}个错误&nbsp;&nbsp;</el-button
            >
          </el-popover>
          <el-button type="primary" @click="submitForm('ruleForm')">提交</el-button>
        </div>
      </div>
    </template>
    
    <script>
    export default {
      data() {
        return {
          errMap: [],
          ruleForm: {
            name: '',
            region: '',
            date1: '',
            date2: '',
            delivery: false,
            type: [],
            resource: '',
            desc: '',
          },
          rules: {
            name: [
              { required: true, message: '请输入活动名称', trigger: 'blur' },
              { min: 3, max: 5, message: '长度在 3 到 5 个字符', trigger: 'blur' },
            ],
            region: [
              { required: true, message: '请选择活动区域', trigger: 'change' },
            ],
            date1: [
              {
                type: 'date',
                required: true,
                message: '请选择日期',
                trigger: 'change',
              },
            ],
            date2: [
              {
                type: 'date',
                required: true,
                message: '请选择时间',
                trigger: 'change',
              },
            ],
            type: [
              {
                type: 'array',
                required: true,
                message: '请至少选择一个活动性质',
                trigger: 'change',
              },
            ],
            resource: [
              { required: true, message: '请选择活动资源', trigger: 'change' },
            ],
            desc: [{ required: true, message: '请填写活动形式', trigger: 'blur' }],
          },
        }
      },
      methods: {
        submitForm(formName) {
          this.$refs[formName].validate(valid => {
            if (valid) {
              alert('submit!')
            } else {
              // 校验失败获取错误信息
              this.getErrorInfo(formName)
              console.log('error submit!!')
              return false
            }
          })
        },
    
        // 获取错误信息
        getErrorInfo(formName) {
          const fields = this.$refs[formName].fields
          let errMap = []
          fields.forEach(item => {
            let obj = {}
            const {
              validateState,
              validateMessage,
              $options: { propsData },
            } = item
            if (validateState === 'error') {
              obj.status = validateState
              obj.text = validateMessage
              obj.prop = propsData.prop
              obj.label = propsData.label
              errMap.push(obj)
            }
          })
          this.errMap = errMap
        },
    
        // 跳到对应的报错字段
        scrollToField(prop) {
          const labelNode = document.querySelector(`label[for="${prop}"]`)
          labelNode && labelNode.scrollIntoView(true)
        },
      },
    }
    </script>
    
    <style scope></style>
    

    相关文章

      网友评论

          本文标题:Element UI 校验form表单 升级版

          本文链接:https://www.haomeiwen.com/subject/xwucfrtx.html