object.assign问题(vue相关)

<template>
 <div>
    <div v-for="item in list2">{{item.name}}{{item.title}}</div>
    <button @click="change">按钮</button>
 </div></template><script type="text/ecmascript-6">export default {
  data() {    return {      list1: { name: "John", id: 1 },      list2: [],
    };
  },
  created() {    this.obj = this.list1    //Object.assign(this.obj,{title:'123'}) //←直接绑定到obj上不会给title绑定get和set所以点击按钮也不会更新视图  
    //↓创建一个新的对象title就能成功绑定get和set~这是什么原理,求解惑
    this.obj = Object.assign({},this.obj,{title:'123'}) 
    console.log(this.obj);    this.list2.push(this.obj)    console.log(this.list2);
  },  methods: {
    change(){      this.list2[0].title='harry'
    }
  }
};</script>

我的理解是vue会直接给新声明对象的所有属性自动绑定set和get~Object.assign把对象合并到新对象上,相当于把合并对象的所有属性重新声明到新对象上所以自动绑了get和set,不知道有没有理解错~


莫回无
浏览 1045回答 2
2回答

千巷猫影

这个和vue的observe实现源码有关了,会观察对象有没有__ob__属性,如果有就不会再去new Observer,如果没有就会去new Observer, Object.assig不会拷贝__ob__(不可枚举的)这个属性相关vue源码如下&nbsp;&nbsp;/** &nbsp;&nbsp;&nbsp;*&nbsp;Attempt&nbsp;to&nbsp;create&nbsp;an&nbsp;observer&nbsp;instance&nbsp;for&nbsp;a&nbsp;value, &nbsp;&nbsp;&nbsp;*&nbsp;returns&nbsp;the&nbsp;new&nbsp;observer&nbsp;if&nbsp;successfully&nbsp;observed, &nbsp;&nbsp;&nbsp;*&nbsp;or&nbsp;the&nbsp;existing&nbsp;observer&nbsp;if&nbsp;the&nbsp;value&nbsp;already&nbsp;has&nbsp;one. &nbsp;&nbsp;&nbsp;*/ &nbsp;&nbsp;function&nbsp;observe(value,&nbsp;asRootData)&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(!isObject(value)&nbsp;||&nbsp;value&nbsp;instanceof&nbsp;VNode)&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return &nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;ob;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;检查是否有__ob__属性 &nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(hasOwn(value,&nbsp;'__ob__')&nbsp;&&&nbsp;value.__ob__&nbsp;instanceof&nbsp;Observer)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ob&nbsp;=&nbsp;value.__ob__; &nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;else&nbsp;if&nbsp;( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;shouldObserve&nbsp;&& &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;!isServerRendering()&nbsp;&& &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(Array.isArray(value)&nbsp;||&nbsp;isPlainObject(value))&nbsp;&& &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Object.isExtensible(value)&nbsp;&& &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;!value._isVue &nbsp;&nbsp;&nbsp;&nbsp;)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ob&nbsp;=&nbsp;new&nbsp;Observer(value); &nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(asRootData&nbsp;&&&nbsp;ob)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ob.vmCount++; &nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;ob &nbsp;&nbsp;}/** &nbsp;&nbsp;&nbsp;*&nbsp;Observer&nbsp;class&nbsp;that&nbsp;is&nbsp;attached&nbsp;to&nbsp;each&nbsp;observed &nbsp;&nbsp;&nbsp;*&nbsp;object.&nbsp;Once&nbsp;attached,&nbsp;the&nbsp;observer&nbsp;converts&nbsp;the&nbsp;target &nbsp;&nbsp;&nbsp;*&nbsp;object's&nbsp;property&nbsp;keys&nbsp;into&nbsp;getter/setters&nbsp;that &nbsp;&nbsp;&nbsp;*&nbsp;collect&nbsp;dependencies&nbsp;and&nbsp;dispatch&nbsp;updates. &nbsp;&nbsp;&nbsp;*/ &nbsp;&nbsp;var&nbsp;Observer&nbsp;=&nbsp;function&nbsp;Observer(value)&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;this.value&nbsp;=&nbsp;value;&nbsp;&nbsp;&nbsp;&nbsp;this.dep&nbsp;=&nbsp;new&nbsp;Dep();&nbsp;&nbsp;&nbsp;&nbsp;this.vmCount&nbsp;=&nbsp;0;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;添加__ob__属性 &nbsp;&nbsp;&nbsp;&nbsp;def(value,&nbsp;'__ob__',&nbsp;this);&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(Array.isArray(value))&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(hasProto)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;protoAugment(value,&nbsp;arrayMethods); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;else&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;copyAugment(value,&nbsp;arrayMethods,&nbsp;arrayKeys); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.observeArray(value); &nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;else&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.walk(value); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;};
打开App,查看更多内容
随时随地看视频慕课网APP