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,不知道有没有理解错~

阅读 3.4k
2 个回答

这个和vue的observe实现源码有关了,会观察对象有没有__ob__属性,如果有就不会再去new Observer,如果没有就会去new Observer, Object.assig不会拷贝__ob__(不可枚举的)这个属性
相关vue源码如下

  /**
   * Attempt to create an observer instance for a value,
   * returns the new observer if successfully observed,
   * or the existing observer if the value already has one.
   */
  function observe(value, asRootData) {
    if (!isObject(value) || value instanceof VNode) {
      return
    }
    var ob;
    // 检查是否有__ob__属性
    if (hasOwn(value, '__ob__') && value.__ob__ instanceof Observer) {
      ob = value.__ob__;
    } else if (
      shouldObserve &&
      !isServerRendering() &&
      (Array.isArray(value) || isPlainObject(value)) &&
      Object.isExtensible(value) &&
      !value._isVue
    ) {
      ob = new Observer(value);
    }
    if (asRootData && ob) {
      ob.vmCount++;
    }
    return ob
  }
/**
   * Observer class that is attached to each observed
   * object. Once attached, the observer converts the target
   * object's property keys into getter/setters that
   * collect dependencies and dispatch updates.
   */
  var Observer = function Observer(value) {
    this.value = value;
    this.dep = new Dep();
    this.vmCount = 0;
    // 添加__ob__属性
    def(value, '__ob__', this);
    if (Array.isArray(value)) {
      if (hasProto) {
        protoAugment(value, arrayMethods);
      } else {
        copyAugment(value, arrayMethods, arrayKeys);
      }
      this.observeArray(value);
    } else {
      this.walk(value);
    }
  };

差不多,data中的属性值更改会重新监听新值

图片描述

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题