Vue => Element form表单方法resetFields无效 使用 Object.assign巧妙重置data数据

350 阅读1分钟

重置数据

如果在搜索想重置数据

  • 千万不要这样去重置
  • 如果有100个数据,那么要100个数据手动区赋值?nonono
  • 在这里插入图片描述

在这里插入图片描述

无法清空

之前遇到resetFields无效时都是自己手动用

this.ruleForm = Object.assign({},this.ruleForm, this.$options.data().ruleForm)

这种方式来清数据,用了这么久的form表单,resetFields真的是有时候生效有时候又不生效的,于是看了下Element源码,终于发现了其中的奥秘
源码的form-item在mounted的时候是这么写的

mounted() {
      if (this.prop) {
        this.dispatch('ElForm', 'el.form.addField', [this]);

        let initialValue = this.fieldValue;
        if (Array.isArray(initialValue)) {
          initialValue = [].concat(initialValue);
        }
        Object.defineProperty(this, 'initialValue', {
          value: initialValue
        });

        this.addValidateEvents();
      }
    },

可以看到整个mounted操作都是基于你定义了prop才可以的,之后就是定义一个initialValue初始值,使用Object.defineProperty来定义默认是不可修改的,加writable属性值才能修改,并且放到this下,然后执行resetFields时把值变成初始值,所以以后需要清空表单,又不想手动清空的那么prop是必须要定义了

基本用法

Object.assign方法用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target)。

const target = { a: 1 };

const source1 = { b: 2 };
const source2 = { c: 3 };

Object.assign(target, source1, source2);
target // {a:1, b:2, c:3}

Object.assign方法的第一个参数是目标对象,后面的参数都是源对象。

注意,如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性。

const target = { a: 1, b: 1 };

const source1 = { b: 2, c: 2 };
const source2 = { c: 3 };

Object.assign(target, source1, source2);
target // {a:1, b:2, c:3}

如果只有一个参数,Object.assign会直接返回该参数。

const obj = {a: 1};
Object.assign(obj) === obj // true

如果该参数不是对象,则会先转成对象,然后返回。

typeof Object.assign(2) // "object"

由于undefined和null无法转成对象,所以如果它们作为参数,就会报错。

Object.assign(undefined) // 报错
Object.assign(null) // 报错

注意点

  • (1)浅拷贝
    Object.assign方法实行的是浅拷贝,而不是深拷贝。也就是说,如果源对象某个属性的值是对象,那么目标对象拷贝得到的是这个对象的引用。
const obj1 = {a: {b: 1}};
const obj2 = Object.assign({}, obj1);

obj1.a.b = 2;
obj2.a.b // 2

上面代码中,源对象obj1的a属性的值是一个对象,Object.assign拷贝得到的是这个对象的引用。这个对象的任何变化,都会反映到目标对象上面。

  • (2)同名属性的替换
    对于这种嵌套的对象,一旦遇到同名属性,Object.assign的处理方法是替换,而不是添加。
const target = { a: { b: 'c', d: 'e' } }
const source = { a: { b: 'hello' } }
Object.assign(target, source)
// { a: { b: 'hello' } }

上面代码中,target对象的a属性被source对象的a属性整个替换掉了,而不会得到{ a: { b: ‘hello’, d: ‘e’ } }的结果。这通常不是开发者想要的,需要特别小心。

一些函数库提供 Object.assign的定制版本(比如 Lodash 的_.defaultsDeep方法),可以得到深拷贝的合并。

Vue组件

  • Vue组件可能会有这样的需求:在某种情况下,需要重置Vue组件的data数据。
  • 此时,我们可以通过this. d a t a 获 取 当 前 状 态 下 的 d a t a , 通 过 t h i s . data获取当前状态下的data,通过this. data获取当前状态下的data,通过this.options.data()获取该组件初始状态下的data。然后只要使用Object.assign(this.$data, this.$options.data())就可以将当前状态的data重置为初始状态
export default {
  data() {
    return {
    a:'',
    b:'',
    c:'',
    systemInfoArr: [],
      unitListArr: [],
      formSelectObj: {
        systemInfo: { // 业务系统列表
          name: 'systemInfo',
          arr: [],
          selectVal: '',
          value: '',
          curSelect: null
        },
        unitList: { // 用户配置系统
          name: 'unitList',
          arr: [],
          selectVal: '',
          value: '',
          curSelect: null
        }
      }
    }
   },
   mounted(){
      // 1.
        Object.assign(this.$data.formSelectObj, this.$options.data().formSelectObj) // 这里重置 formSelectObj 数据,其他不受影响
      // 2.
        Object.assign(this.$data, this.$options.data()) // 这里重置 data 下的所有数据
}
}