element ui中 el-dialog关闭窗口清空表单验证

788 阅读3分钟

resetFields() 清空表单时机

关于form的resetFields()方法

(1)此方法就是把formData的值设置为初始值.

(2) 而这个初始值是在form的生命周期函数mounted被调用的时候赋值上去的。

(3)所以,在form mounted之前,如果给formData赋值了,那么后面调用resetFields()方法的时候,formData的值都不会变成空字符串。会出问题的场景
使用dialog弹出form表单的时候,由于需要,可能会给表达赋初始值,比如编辑操作的时候,会从外面传入数据,赋值到表单上。一般会在dialog的open函数里写赋值语句。如果是第一次弹出的话,此时form是还没有mounted结束的。这个时候就会出现上面说的情况,调resetFields()的时候,表单不会被重置为空字符串。
解决办法。在open方法里,不要直接做赋值操作,加上 this.$nextTick方法在这个方法里做操作。这个时候form已经mounted结束了。亲测成功!

image.png

点击了编辑 再点击新增发现存在编辑赋的值

image.png

<template>
  <div>


    <el-dialog :visible.sync="dialogVisible" @closed="dialogClosed('dialogForm')">
      <el-form :model="dialogForm" :rules="rules" ref="dialogForm">
        <el-form-item label="活动foo" prop="foo">
          <el-input v-model="dialogForm.foo" clearable></el-input>
        </el-form-item>
        <el-form-item label="活动bar" prop="bar">
          <el-input v-model="dialogForm.bar" clearable></el-input>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="submitForm('dialogForm')">立即创建</el-button>
          <el-button @click="resetForm('dialogForm')">重置</el-button>
          <el-button @click="dialogVisible = false">取消</el-button>

        </el-form-item>
      </el-form>
    </el-dialog>
    <el-button @click="showDialog">编辑dialogVisible</el-button>
    <el-button @click="start">新增dialogVisible</el-button>
  </div>
</template>

<script>


export default {
  components: {
    Input,
    Input1
  },
  name: "",
  created() {

  },
  mounted() {

  },
  data() {
    return {
      dialogForm: {
        foo: '',
        bar: ''
      },
      dialogVisible: false,
      rules: {
        foo: [
          { required: true, message: '请输入活动名称', trigger: 'blur' },
        ],
        bar: [
          { required: true, message: '请输入活动名称', trigger: 'blur' },
        ],
      }
    };
  },
  computed: {

  },
  methods: {
    start() {
      this.dialogVisible = true
      console.log('新增--this.dialogForm', this.dialogForm);
    },
    submitForm(formName) {
      this.$refs[formName].validate((valid) => {
        if (valid) {
          alert('submit!');
        } else {
          console.log('error submit!!');
          return false;
        }
      });
    },
    resetForm(formName) {
      this.$refs[formName].resetFields();
    },
    showDialog() {
      this.dialogVisible = true;
      // this.dialogForm = {
      //   id: 1,
      //   foo: '张三',
      //   bar: '118',
      // }
      this.dialogForm.foo = "张三"
      this.dialogForm.bar = 118
      console.log('编辑--this.dialogForm', this.dialogForm);
    },
    dialogClosed(formName) {
      this.$refs[formName].resetFields(); // 重置表单移除校验
      console.log("结束--this.dialogForm", this.dialogForm);
    },
  }
};
</script>

<style lang="scss"  scoped>

</style>

原因:

  • 一开始弹窗隐藏时,弹窗样式加上了display: none 属性。
  • display: none 属性的作用:将元素从DOM结构中完全移除。
  • 而表单是放在弹窗里的,意味着表单一开始不会出现在页面结构中,此时data 中的默认数据formData 并没有作用上表单。
  • 当点击修改时,触发handleEdit() 方法,修改了formData 。此时弹窗打开,新的formData 作用上表单,并且表单将新的formData ,当作了初始数据

resetFields()方法只是将表单赋为初始值,表单的初始值是在mounted中赋给dom,也就是第一次渲染的时候。因此如果第一次是编辑,我将回显的信息赋值给表单, 如果第一次是新增-关闭弹窗-再次打开-点击编辑-关闭弹窗 显示的是空值

dialog2GIF.gif dialogGIF.gif

方法一:就是想办法让表单吃上原始的formData 。

原来是先赋数据,再打开弹窗。那么现在改为先打开弹窗,再赋数据。

最好就是在等form加载完(初始值为this中定义的空值)

 showDialog() {
      this.dialogVisible = true;
      // this.dialogForm = {
      //   id: 1,
      //   foo: '张三',
      //   bar: '118',
      // }
      //this.dialogForm.foo = "张三"
      //this.dialogForm.bar = 118
       this.$nextTick(() => {
         this.dialogForm.foo = "张三"
         this.dialogForm.bar = 118
      })
      console.log('编辑--this.dialogForm', this.dialogForm);
    },

方法二:先调用resetFields()重置表单并移除校验结果,然后将表单数据对象置空。

     this.$refs[formName].resetFields(); // 重置表单移除校验
      for (var key in this.dialogForm) {//hasOwnProperty用来检测属性是否为对象的自有属性,
        if (this.dialogForm.hasOwnProperty(key)) {
          this.dialogForm[key] = '';
        }
      }

方法三:直接在dialog关闭的时候 重置数据清空校验提示

 /*  最优方案---------- */
      this.dialogForm = {
        foo: '',
        bar: '',
      }
      this.$nextTick(() => {
        this.$refs.dialogForm.clearValidate()
      })
      /*  最优方案---------- */

方法四 直接在open做重置以及赋值

blog.csdn.net/Misko/artic…

完整代码:

<template>
  <div>
    <!-- <Input />
    <Input1 /> -->

    <el-dialog :visible.sync="dialogVisible" @closed="dialogClosed('dialogForm')"
      @open="openFun('dialogForm')">
      <el-form :model="dialogForm" :rules="rules" ref="dialogForm">
        <el-form-item label="活动foo" prop="foo">
          <el-input v-model="dialogForm.foo" clearable></el-input>
        </el-form-item>
        <el-form-item label="活动bar" prop="bar">
          <el-input v-model="dialogForm.bar" clearable></el-input>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="submitForm('dialogForm')">立即创建</el-button>
          <el-button @click="resetForm('dialogForm')">重置</el-button>
          <el-button @click="dialogVisible = false">取消</el-button>

        </el-form-item>
      </el-form>
    </el-dialog>
    <el-button @click="showDialog">编辑dialogVisible</el-button>
    <el-button @click="start">新增dialogVisible</el-button>
  </div>
</template>

<script>
import Input from '@/components/Write/Input.vue'
import Input1 from '@/components/Write/Input1.vue'

export default {
  components: {
    Input,
    Input1
  },
  name: "",
  created() {

  },
  mounted() {

  },
  data() {
    return {
      dialogForm: {
        foo: '',
        bar: ''
      },
      dialogVisible: false,
      rules: {
        foo: [
          { required: true, message: '请输入活动名称', trigger: 'blur' },
        ],
        bar: [
          { required: true, message: '请输入活动名称', trigger: 'blur' },
        ],
      }
    };
  },
  computed: {

  },
  methods: {
    openFun(formName) {//弹框回调
      this.$nextTick(() => {
        if (this.$refs[formName]) {
          this.$refs[formName].resetFields();
        }
      });
    },

    start() {
      this.dialogVisible = true
      console.log('新增--this.dialogForm', this.dialogForm);
    },
    submitForm(formName) {
      this.$refs[formName].validate((valid) => {
        if (valid) {
          alert('submit!');
        } else {
          console.log('error submit!!');
          return false;
        }
      });
    },
    resetForm(formName) {
      this.$refs[formName].resetFields();
    },
    showDialog() {
      this.dialogVisible = true;
      // this.dialogForm = {
      //   id: 1,
      //   foo: '张三',
      //   bar: '118',
      // }
      this.dialogForm.foo = "张三"
      this.dialogForm.bar = 118
      // this.$nextTick(() => {
      //   this.dialogForm.foo = "张三"
      //   this.dialogForm.bar = 118
      // })
      console.log('编辑--this.dialogForm', this.dialogForm);
    },
    dialogClosed(formName) {
      // this.$refs[formName].resetFields(); // 重置表单移除校验
      // for (var key in this.dialogForm) {//hasOwnProperty用来检测属性是否为对象的自有属性,
      //   if (this.dialogForm.hasOwnProperty(key)) {
      //     this.dialogForm[key] = '';
      //   }
      // }


      console.log("结束--this.dialogForm", this.dialogForm);

      /*  最优方案---------- */
      // this.dialogForm = {
      //   foo: '',
      //   bar: '',
      // }
      // this.$nextTick(() => {
      //   this.$refs.dialogForm.clearValidate()
      // })
      /*  最优方案---------- */
    },
  }
};
</script>

<style lang="scss"  scoped>

</style>

参考:

segmentfault.com/a/119000001…

www.cnblogs.com/cry0-0/arch…