编辑时使用Object.assign({},row) el-form表单无法编辑 el-select赋值后不能编辑

场景:

页面有新增,编辑,删除按钮,可以编辑表格中的某行数据,页面表格数据是从后台获取的,点击编辑打开dailog,将那行数据赋给ruleForm,发现Form表单无法编辑了,select多选框无法选择,删除,datepicker等组件也会出现这种不能编辑的情况。

select代码如下

<el-select style="margin:0 5px" 
	v-model="ruleForm.selectValue" 
	clearable 
	placeholder="类型">
    <el-option v-for="item in group" :key="item.value" :label="item.type" :value="item.value"></el-option>
</el-select>

后台返回数据为row,通过Object.assign进行拷贝

this.ruleForm = Object.assign({},row)    //this.ruleForm为表单数据,row为后台返回的数据信息

原因:

通过Object.assign直接将后台返回的数据赋值给form,后台返回的数据中没有select model 绑定的数据,而vue 无法监听动态新增的属性的变化
data中定义的属性为

ruleForm :{
   name:null,
   selectValue:null, //select绑定的值
   age:null,
   address:null
}

而后台返回的数据中没有selectValue属性,如下

temp:{
   name:null,
   age:null,
   address:null
}

解决:

  • 拷贝时加上初始化时的数据格式
this.ruleForm = Object.assign({},this.ruleForm,row)
  • 用 $set 来为这些属性赋值.
  <el-select style="margin:0 5px" 
  	v-model="ruleForm.selectValue"
  	@change="$set(ruleForm,ruleForm.selectValue,$event)" 
  	clearable 
 	placeholder="类型">
         <el-option v-for="item in group" :key="item.value" :label="item.type" :value="item.value"></el-option>
  </el-select>

浅拷贝和深拷贝

  • 浅拷贝: 将原对象或原数组的引用直接赋给新对象,新数组,新对象/数组只是原对象的一个引用
  • 深拷贝: 创建一个新的对象和数组,将原对象的各项属性的“值”(数组的所有元素)拷贝过来,是“值”而不是“引用”

有时候希望在改变新的数组(对象)的时候,不改变原数组(对象)
例如:var newObj = obj; newObj.xxx = xxx 实际上,newObj和obj两个引用指向的是同一个对象,修改了newObj,也就等同于修改了obj。

Object.assign()实现浅复制。

  • 合并之后所有被合并的对象和合并的对象都会变
  • 如果目标对象中的属性具有相同的键,则它们将被源中的属性覆盖。后来的消息来源的属性将同样覆盖较早的属性。

场景如下:

if(lable ===  '1'){
 this.first= Object.assign([],row);
}else if(lable ===  '2'){
 this.second= Object.assign([],row);
}
console.log(this.first) 
console.log(this.second) 

这时会发现当label为1时,this.second的值也被改写成与this.first相同的数据

文档中的例子

const target = { a: 1, b: 2 };
const source = { b: 4, c: 5 };

const returnedTarget = Object.assign(target, source);

console.log(target);	// expected output: Object { a: 1, b: 4, c: 5 }

console.log(returnedTarget);	// expected output: Object { a: 1, b: 4, c: 5 }

赋值后原本的target也发生了变化,并且b的值变为5
因此在实际项目中,我们为了不改变源对象。一般会把目标对象传为{}

Object.assign() 可以把任意多个源对象自身可枚举的属性拷贝给目标对象,然后返回目标对象。第一参数即为目标对象。

  • 如果目标对象与源对象有同名属性,则后面的属性会覆盖前面的属性
  • 如果只有一个参数,则直接返回该参数。即Object.assign(obj) === obj
  • 如果第一个参数不是对象,而是基本数据类型(Null、Undefined除外),则会调用对应的基本包装类型
  • 如果第一个参数是Null和Undefined,则会报错;如果Null和Undefined不是位于第一个参数,则会略过该参数的复制
  let o1 = { a: 0 , b: { c: 0}};
  let o2 = Object.assign({}, o1);
  console.log(JSON.stringify(o2)); // { a: 0, b: { c: 0}}

  o1.a = 1;
  console.log(JSON.stringify(o1)); // { a: 1, b: { c: 0}}
  console.log(JSON.stringify(o2)); // { a: 0, b: { c: 0}}

  o2.b.c = 3;
  console.log(JSON.stringify(o1)); // { a: 1, b: { c: 3}}//c属性也发生了改变
  console.log(JSON.stringify(o2)); // { a: 1, b: { c: 3}}

Object.assign 不会跳过那些值为 null 或 undefined 的源对象。

场景如下:

o1 = {a:1, b:null }
o2 = Object.assign(o1, {a:2,b:3} ); 	//{a: 2, b: 3}

因此一定要检查后端返回的数据里,有没有属性值为 null或者 undefined,null 和undefined 禁止出现在正常的数据格式中

  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值