现象

resetFields作用实际上是将表单元素置为初始值。

使用resetFields清空表单,有时候会出现再次打开表单,还是会出现上一次的值的情况,下面就要分析下这个问题的原因:

分析

demo

<template>
  <div>
    <el-table :data="data">
      <el-table-column prop="name" label="用户名"></el-table-column>
      <el-table-column prop="age" label="年龄"></el-table-column>
      <el-table-column label="操作">
        <template slot-scope="scope">
          <el-button @click="edit(scope.row)">编辑</el-button>
        </template>
      </el-table-column>
    </el-table>
    <el-button @click="open">打开</el-button>
    <el-form :model="formData" size="small" ref="form" v-if="dialog">
      <el-form-item label="用户名" prop="name">
        <el-input v-model.number="formData.name" style="width:200px"></el-input>
      </el-form-item>
      <el-form-item label="年龄" prop="age">
        <el-input v-model.number="formData.age" style="width:200px"></el-input>
      </el-form-item>
      <el-button type='primary' size="small" @click="submit">确认</el-button>
    </el-form>
  </div>
</template>
<script>
export default {
  data(){
    return {
      dialog:false,
      data:[
        {name:'1',age:'1'},
        {name:'2',age:'2'},
        {name:'3',age:'3'},
        {name:'4',age:'4'},
        {name:'5',age:'5'}
      ],
      formData:{ name:'0',age:'0'}
    }
  },
  methods:{
    edit(row){
      this.dialog = true;
        this.formData = {...row} //应该使用浅拷贝,否则子组件修改数据后,父组件数据也会被修改
    },
    submit(){
      this.dialog = false;
      this.$refs.form.resetFields()   //会reset成初始值
    },
    open(){
      this.dialog = true;
    }
  }
}
</script>

分析

  • 场景一:Form使用了v-if
<el-form :model="formData" size="small" ref="form" v-if="dialog">

每次打开Form,都会给model绑定的formData重新赋值,这个值就是初始值,关闭表单时,formData就会被置为初始值,所以下一次打开表单,就会出现上一次表单的结果
在这里插入图片描述
这种情况下,每次打开,都会回填上一次的结果,会影响用户使用

  • 场景二:Form使用了v-show
<el-form :model="formData" size="small" ref="form" v-if="dialog">

因为使用v-show时,组件渲染时,表单也会进行初始化
在这里插入图片描述
这样情况下,就不会有问题,每次打开会回填data中声明的formData的值

  • 场景三:From是在Dialog中
<el-dialog :visible="dialog" v-if="dialog">
  <el-form :model="formData" size="small" ref="form">
</el-dialog>

可以看下图el-dialog的源码,el-dialog的内容和rendered属性挂钩,rendered属性和visible相关
在这里插入图片描述
在这里插入图片描述
但是由于el-dialog的内容使用v-if,所以实际上,加了Dialog的场景,和场景一一样:每次打开Dialog,其中的内容都会重新渲染,因此Form每次都会重新赋值,关闭后,就会给Form回填赋值的初始值,所以会出现和场景一一样的问题。
注意:这种场景和Dialog本身是否使用v-if 还是v-show没有关系,之前看到有一个解决方案是Dialog加上v-if是无效的

解决方案
  1. 编辑打开弹窗时,在$nextTick中给model赋值,此时Dialog已经初始化(已经mounted)
edit(row){
  this.dialog = true;
  this.$nextTick(()=>{
    this.formData = {...row}
  })
},
  1. 关闭弹窗时,不使用resetFields(),直接赋值:this.formData = {}
    但这样会引入另一个问题,如果使用了Form表单,此时回填的是空对象,如果有不能填空的校验,会出现表示错误的红色校验信息
this.formData = {}
//this.$refs['form'].clearValidate() //这样也不行,clearValidate()只是移除当前的校验结果,不是移除校验器,所以this.data = {}仍然会出现表示错误的红色校验信息

参考

form resetFields并没有清空表单

Logo

前往低代码交流专区

更多推荐