vue的watch对象问题

<template>
  <div>
   <button @click="changeObj">click</button>
  </div>
</template>

<script>
export default {
  name: "HelloWorld",
  data() {
    return {
      msg: "Welcome to Your Vue.js App",
      obj: {
        attr1: {},
        attr2: {}
      }
    };
  },
  computed: {
    attr2() {
      return this.obj.attr2;
    }
  },
  mounted() {
    // this.obj = this.obj1;
  },
  watch: {
    attr2: {
      deep: true,
      handler(o, v) {
        console.log("change");
        console.log(o);
        console.log(v);
      }
    }
  },
  methods: {
    changeObj() {
      this.$set(this.obj, "attr3", {});
    }
  }
};
</script>

控制台打印的是

clipboard.png

在我点击之后为什么可以监听到attr2的变化?
有什么办法可以让attr2不发生变化呢?(即一个对象的各个属性都是独立监听)
阅读 2.1k
2 个回答
在我点击之后为什么可以监听到attr2的变化?

抛砖引玉,在这说一下自己对第一个问题的粗浅理解,有不对的地方希望大家批评指正。
1、初始化计算属性attr2的时候,attr2的Watcher会被(this.obj的dep、childOb.dep)和(this.obj.attr2的dep、childOb.dep)收集到。这样就保证了一旦this.obj或this.obj.attr2的值有变化,会更新计算属性attr2。
2、

this.$set(this.obj, "attr3", {});

这句代码会触发this.obj._ob_.dep的notify()方法(简单理解就是this.obj的值改变了触发更新),因为第一步this.obj的childOb.dep已经收集到了计算属性attr2的Watcher,所以会触发计算属性attr2的更新。
3、
因为

watch: {
    attr2: {
      deep: true,
      handler(o, v) {
        console.log("change");
        console.log(o);
        console.log(v);
      }
    }
  },

在此watch了attr2的变化,因此触发了回调,监听到了计算属性attr2的变化。

注意:this.obj.attr2和计算属性attr2是两个不同的属性,楼主的命名有点让人迷惑- -。

  watch: {
    'obj.attr1': { //'对象.要监听的属性名'
      immediate: true,
      handler(val) {
        
      }
    }
  },
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题