欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

ElementUI的表单验证失效,出现意想不到的问题

程序员文章站 2022-03-09 11:26:30
...

起因

项目中有一个心理测试模块,需要实现修改功能。
ElementUI的表单验证失效,出现意想不到的问题

尝试一

页面渲染之前,created时,发送一个请求,拿到该测试问卷的基本信息(名称、简介、测试结果等),该值命名为testData。

created(){
   const data = {
   	params: {id: this.$route.query.id}
   	}
   this.apiGet('***/***/getQuestionById', data).then(res => {
   	this.testData = res.data[0]
  }
}

问题

点击修改问卷,让form表单里填充testData的值。这样bug就来了,我在form表单里修改testData.title的值的同时,页面左上角的title也跟着改变。因为左上角的值和input框里的值绑定的是同一个值,这时,如果我在input框里修改title的值,但是点击取消,不提交表单。按需求来说,该title是不应该被修改的,但是实际上被修改了。这时,用户只能通过刷新的方式,重新获取该问卷的基本信息。

解决

我想到可以用vue里的.lazy方式,让输入框里的值在修改的同时,左上角的值不会同时改变。但是一旦input框失去焦点,该值还是被改变了。所以这样也行不通。

尝试二

我重新申请一个变量formData,用来存放testData。此处一定要注意通过 值引用 赋值,不要把地址赋值过去了。在尝试一中,created时,获取到testData后,就给formData赋值。

created(){
   const data = {
   	params: {id: this.$route.query.id}
   	}
   this.apiGet('***/***/getQuestionById', data).then(res => {
   	this.testData = res.data[0]
   }
   this.testForm.title = this.testData.title
   this.testForm.abstract = this.testData.abstract
   this.testForm.value = this.testData.value
   this.testForm.result = this.testData.result
}

表单部分代码如下

  <el-dialog title="修改测试问卷" :visible.sync="dialogTestVisible" width="40%">
    <el-form :model="testForm" ref="editTestForm">
      <el-form-item label-width="18%" label="问卷名称:" prop="title" 
                    :rules="{ required: true, message: '问卷名称不能为空', trigger: 'blur' }">
        <el-input v-model="testForm.title" autocomplete="off" placeholder="输入问卷名称"></el-input>
      </el-form-item>
    </el-form>
    <div slot="footer" class="dialog-footer">
      <el-button type="primary" class="pull-left" @click="addDomain()">新增选项</el-button>
      <el-button class="pull-left" @click="resetForm('editTestForm')">重置选项</el-button>
      <el-button @click="dialogTestVisible = false">取 消</el-button>
      <el-button type="primary" @click="editTestDialog('editTestForm')" :loading="isLoading">确 定</el-button>
    </div>
  </el-dialog>

表单提交代码

    editTestDialog(formName){
      this.$refs[formName].validate((valid) => {
      	if (valid) {
          const data = {
            id: this.id,
            type: 0,
            title: this.testForm.title,
            abstract: this.testForm.abstract,
            value: this.testForm.value,
            result: this.testForm.result
          }
          this.apiPost('admin/MentalTest/QuestionEdit',data).then((res) => {
            this.handelResponse(res, (data) => {
              if(res.code === 200){
                _g.toastMsg('success', "修改试题成功")
                this.dialogTestVisible = false
                setTimeout(() => {
                  _g.shallowRefresh_({name: this.$route.name, query: this.$route.query})
                }, 0)
              }else{
                _g.toastMsg('error', "修改试题失败")
              }
            })
          })
        } else {
          _g.toastMsg('error', "修改试题失败")
          return false;
        }
      });
    }

问题

点击修改,模态框里都能正确渲染该问卷的数据,但是这时表单的验证不起作用了。input框值为空,验证能通过,input框值不为空时,验证不通过,提示值为空。

情况一

点击修改,模态框正确渲染数据后,把input框置空,不提示input框值为空。此时,点击提交,valid为true,表单成功提交,title的值被修改成了空。表单验证出了问题,我一步步排查也排查不出来到底是哪出了错。
ElementUI的表单验证失效,出现意想不到的问题

情况二

基于上面的情况一,测试问卷的title被修改成了空。
点击修改,模态框正确渲染数据,input框值确实为空。但是如果在input框里输入值,点击提交,表单却验证不通过,valid为false,无法提交表单。
ElementUI的表单验证失效,出现意想不到的问题

解决

我一直都怀疑是自己某个地方出现了低级的拼写错误,但是一个字母一个字母检查,确实没有错误,但是又找不到其他错误。而且,其他的表单验证很正常,都是相同的逻辑。比如,表格里的修改,就是修改该测试问卷某一个问题的信息(如问题内容,选项内容,选项分值等),该表单验证非常顺利,和预想的一样,input值为空,提示不能为空,不为空时,表单顺利提交。
对比两个表单,逻辑是一样的,但是前者表单验证就出现了错误。我也对比了两个表单的代码,思路一模一样,也没有任何低级错误。

最后,我想到了一个 不同之处!!!

点击修改问卷前,formData就已经有值了,点击修改问卷后,数据渲染。
而表格里的修改呢?点击修改之后,会发送一个请求,根据id获取该题目的信息,然后数据渲染到表单上。

尝试三

在点击修改问卷后,重新发送一次请求,获取该问卷的信息,赋值给formData。而不是在整个页面渲染之前,获取到testData之后就赋值给formData。这样,既不会有尝试一中出现的,左上角的title随着input框里的值改变而改变,也不会有尝试二中出现的,表单验证出错。

修改后的代码如下
不在created时获取fromData,而是在触发点击,editTestBtn函数中,重新发送请求,获取testForm。

	editTestBtn(){
      this.dialogTestVisible = true
      // 获取该问卷的基本信息
      const data = {
        params: {
          id: this.$route.query.id
        }
      }
      this.apiGet('***/***/getQuestionById', data).then(res => {
        this.testForm = res.data
      })
    }

总结

虽然表单验证bug解决了,但是为什么会造成,表单验证出错,这种情况,我还了解的不够深入,希望有大神指点!