• el-autocomplete 必填校验问题


    需求描述

    • 表单中,权限编号是远程搜索组件 el-autocomplete,该组件绑定值为 String 类型
    • 提交时,业务需求需要传递权限编号整个对象的值,包括 fetchIdfetchName
    • 因此需要监听 el-autocomplete 的选择事件,拿到选择的对象,赋值给提交参数
      在这里插入图片描述

    初步逻辑

    <el-form ref="form" :model="form" label-width="80px" :rules="rules" class="form">
      <el-form-item label="姓名" prop="inputText">
        <el-input v-model="form.inputText" placeholder="请输入内容">el-input>
      el-form-item>
      <el-form-item label="居住地" prop="selectVal">
        <el-select v-model="form.selectVal" placeholder="请选择">
          <el-option
            v-for="item in options"
            :key="item.value"
            :label="item.label"
            :value="item"
            value-key="value"
          >
          el-option>
        el-select>
      el-form-item>
      <el-form-item label="权限编号" prop="fetchVal">
        <el-autocomplete
          v-model="form.fetchValFilter"
          placeholder="请输入内容"
          @select="handleSelect"
          :fetch-suggestions="querySearchAsync"
          value-key="fetchName"
        >el-autocomplete>
      el-form-item>
      <el-button type="primary" @click="onSubmit">提交el-button>
    el-form>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 远程搜索方法,模拟接口
    // 远程搜索方法
    querySearchAsync(searchText, cb) {
      console.log("远程搜索输入内容", searchText);
      this.form.fetchVal = {};
      // 模拟接口
      setTimeout(() => {
        let result = [];
        for (var i = 0; i < 10; i++) {
          result.push({
            fetchId: (i + 1) * 1,
            fetchName: "12345_" + (i + 1) * 1,
          });
        }
        console.log("远程搜索获取到的列表", result);
        cb(result);
      }, 300);
    },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 监听到的远程搜索的选择事件
    // 选中远程搜索列表的值
    handleSelect(item) {
       console.log("选择的对象", item);
       this.form.fetchVal = item;
    },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • rules 中,关于远程搜索的校验,应该是判断 this.form.fetchVal 对象中是否包含 fetchIdfetchName
    rules: {
      inputText: [{ required: true, message: "请填写内容", trigger: "blur" }],
      selectVal: [
        {
          required: true,
          validator: (rule, value, callback) => {
            if (this.form.selectVal && this.form.selectVal.value) {
              callback();
            } else {
              callback(new Error("请选择内容"));
            }
          },
          trigger: "change",
        },
      ],
      fetchVal: [
        {
          required: true,
          validator: (rule, value, callback) => {
            console.log("change 事件被触发,开启校验");
            console.log("校验的是对象");
            if (this.form.fetchVal && this.form.fetchVal.fetchId) {
              callback();
            } else {
              callback(new Error("请选择内容"));
            }
          },
          trigger: "change",
        },
      ],
    },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    问题出现

    • 校验表单时,如果 el-autocomplete 的触发为 change,则在输入的过程中,就会触发。此时还未执行 select 事件,this.form.fetchVal 为空对象,则会进入到校验抛错的判断中
      在这里插入图片描述
    • 校验表单时,如果 el-autocomplete 的触发为 blur,在选中结果后,会先触发 blur 事件,后触发 select 事件,依旧拿不到 this.form.fetchVal ,会进入到校验抛错的判断中
    fetchVal: [
      {
        required: true,
        validator: (rule, value, callback) => {
          console.log("blur 事件被触发,开启校验");
          console.log("this.form.fetchVal", this.form.fetchVal);
          if (this.form.fetchVal && this.form.fetchVal.fetchId) {
            callback();
          } else {
            callback(new Error("请选择内容"));
          }
        },
        trigger: "blur",
      },
    ],
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    在这里插入图片描述

    解决方式

    方法一:延时操作

    • blur 会比 select 先触发,那么添加定时器,做一个延时,可以手动将判断放到 select 事件的后面
    fetchVal: [
     {
       required: true,
       validator: (rule, value, callback) => {
         console.log("blur 事件被触发");
         console.log("this.form.fetchVal", this.form.fetchVal);
         setTimeout(() => {
           console.log('此时才开启校验');
           console.log("this.form.fetchVal", this.form.fetchVal);
           if (this.form.fetchVal && this.form.fetchVal.fetchId) {
             callback();
           } else {
             callback(new Error("请选择内容"));
           }
         }, 200);
       },
       trigger: "blur",
     },
    ],
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    在这里插入图片描述

    方法二:手动控制触发校验的方式

    • 移除 rules 中的校验,在提交校验之前,为当前项添加校验规则。或者在选中结果后为当前项添加校验规则,之后校验此项
    // 选中远程搜索列表的值
    handleSelect(item) {
      this.form.fetchVal = item;
      // 添加校验规则
      this.$refs.form.rules.fetchVal[0].validator = (rule, value, callback) => {
        if (this.form.fetchVal && this.form.fetchVal.fetchId) {
          callback();
        } else {
          callback(new Error("请选择内容"));
        }
      };
      // 对当前项进行校验
      this.$refs.form.validateField("fetchVal", (valid) => {
        if (valid) {
          console.log("对当前项进行校验-校验通过了");
        }
      });
    },
    // 提交
    onSubmit() {
      console.log("form", this.form);
      // 添加校验规则
      this.$refs.form.rules.fetchVal[0].validator = (rule, value, callback) => {
        if (this.form.fetchVal && this.form.fetchVal.fetchId) {
          callback();
        } else {
          callback(new Error("请选择内容"));
        }
      };
      // 开启校验
      this.$refs.form.validate((valid) => {
        if (valid) {
          console.log("整个表单进行校验-校验通过了");
        }
      });
    },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    完整代码

    export default {
      data() {
        return {
          form: {
            inputText: "",
            selectVal: {},
            fetchVal: {}, // 远程搜索获取的对象
            fetchValFilter: "", // 远程搜索输入值
          },
          rules: {
            inputText: [{ required: true, message: "请填写内容", trigger: "blur" }],
            selectVal: [
              {
                required: true,
                validator: (rule, value, callback) => {
                  if (this.form.selectVal && this.form.selectVal.value) {
                    callback();
                  } else {
                    callback(new Error("请选择内容"));
                  }
                },
                trigger: "change",
              },
            ],
            fetchVal: [
              {
                required: true,
                validator: (rule, value, callback) => {},
                trigger: "blur",
              },
            ],
          },
          options: [
            { label: "北京", value: 1 },
            { label: "天津", value: 2 },
            { label: "上海", value: 3 },
            { label: "重庆", value: 4 },
          ],
        };
      },
      mounted() {},
      methods: {
        // 远程搜索方法
        querySearchAsync(searchText, cb) {
          console.log("远程搜索输入内容", searchText);
          this.form.fetchVal = {};
          // 模拟接口
          setTimeout(() => {
            let result = [];
            for (var i = 0; i < 10; i++) {
              result.push({
                fetchId: (i + 1) * 1,
                fetchName: "12345_" + (i + 1) * 1,
              });
            }
            console.log("远程搜索获取到的列表", result);
            cb(result);
          }, 300);
        },
        // 选中远程搜索列表的值
        handleSelect(item) {
          this.form.fetchVal = item;
          // 添加校验规则
          this.$refs.form.rules.fetchVal[0].validator = (rule, value, callback) => {
            if (this.form.fetchVal && this.form.fetchVal.fetchId) {
              callback();
            } else {
              callback(new Error("请选择内容"));
            }
          };
          // 对当前项进行校验
          this.$refs.form.validateField("fetchVal");
        },
        // 提交
        onSubmit() {
          console.log("form", this.form);
          // 添加校验规则
          this.$refs.form.rules.fetchVal[0].validator = (rule, value, callback) => {
            if (this.form.fetchVal && this.form.fetchVal.fetchId) {
              callback();
            } else {
              callback(new Error("请选择内容"));
            }
          };
          // 开启校验
          this.$refs.form.validate((valid) => {
            if (valid) {
              console.log("整个表单进行校验-校验通过了");
            }
          });
        },
      },
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
  • 相关阅读:
    瑞吉外卖Day06
    设计模式 - 观察者模式
    【lwip】005-lwip内核框架剖析
    Echarts直角坐标系x轴y轴属性设置大全
    【运维知识进阶篇】集群架构-Nginx高可用Keepalived
    【C语言】结构体详解
    Qt扩展-Advanced-Docking 简介及配置
    C++入门刷题练习(附代码、思路以及相关拓展)
    Opencv中的直方图均衡
    Day04--实现本地生活的首页基础布局
  • 原文地址:https://blog.csdn.net/weixin_42154189/article/details/132852378