总结基于VUE2.x的wach属性监听数组、对象的行为总结

本文详细介绍了Vue2.x中watch监听数组和对象的行为模式,包括数组的push、splice、直接修改及通过set方法修改的情况,以及对象属性的增删改。文中通过实例代码展示了监听数组和对象变化的效果,并提到了数组组件间传递时的行为。重点突出了直接修改数组元素和对象属性无法触发watch监听的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

由于vue3.x发布后,watch属性的行为模式有所变化。在日常使用中会经常搞混或搞不清楚watch是否会监听到事件的变化。这里记录VUE2.x中watch监听数组/对象的行为模式。作为日后迷糊时的提醒。

总结

普通数组
  1. 数组push时,可以监听到数组变化,页面内容即时刷新。
  2. 通过splice删除数组元素时,可以监听到数组变化,页面内容即时刷新。
  3. 直接修改数组元素的值时,不能监听到数组变化,页面内容不会刷新。
  4. 通过set函数修改追加新的元素时,会触发监听事件并且页面即时刷新。
对象数组
  1. 数组push时,可以监听到数组变化,页面内容即时刷新。
  2. 通过splice删除数组元素时,可以监听到数组变化,页面内容即时刷新。
  3. 直接修改数组元素中的属性值时,不能监听到数组变化,页面内容即时刷新
普通对象

属性的增加删除更新都不会触发watch事件。也不会触发画面刷新。

数组组件间传递
  1. 普通数组,触发行为与当前组件中相同。
  2. 对象数组,触发行为与当前组件中相同。

代码

在这里插入图片描述

//WatchArray.vue
<template>
  <div class="hello">
    <section>
      <h2>监听数字数组</h2>
      <button @click="addNumberArr">增加数字元素</button>
      <button @click="deleteNumberArr">删除元素</button>
      <button @click="updateNumberArr">通过下标直接更新元素</button>
      <button @click="updateNumberArrBySet">通过SET更新元素</button>
      <button @click="addNumberArrBySet">通过SET新增元素</button>
      <ul>
        <li
          v-for="item in arr"
          :key="item"
        >{{item}}</li>
      </ul>
    </section>
    <section>
      <div>
        <h2>监听对象数组</h2>
        <button @click="addObjectArr">增加对象元素</button>
        <button @click="deleteObjectArr">删除对象元素</button>
        <button @click="updateObjectArr">更新元素</button>
        <ul>
          <li
            v-for="item in objArr"
            :key="item.id"
          >{{item.lable}}</li>
        </ul>
      </div>
    </section>
    <section>
      <h2>监听对象属性变化测试</h2>
      <button @click="addObjectAttribute">增加属性</button>
      <button @click="deleteObjectAttribute">删除属性</button>
      <button @click="updateObjectAttribute">更新属性</button>
      <br>
      <span>{{ obj }}</span>
      <br>
      <br>
    </section>
    <section>
      <div>
        <button @click="addChildNumberArr">增加子级数字元素</button>
        <button @click="deleteChildNumberArr">删除子级元素</button>
        <button @click="updateChildNumberArr">更新子级元素</button>
      </div>
      <div>
        <button @click="addChildObjectArr">增加子级对象元素</button>
        <button @click="deleteChildObjectArr">删除子级对象元素</button>
        <button @click="updateChildObjectArr">更新子级元素</button>
      </div>
      <WachCHild
        :arr="childArr"
        :objArr="childObjArr"
      />
    </section>
  </div>
</template>

<script>
import WachCHild from "./WatchChild.vue";
export default {
  name: "WatchArray",
  components: {
    WachCHild,
  },
  data: function () {
    return {
      arr: [1, 2, 3, 4, 5],
      objArr: [{ id: "0", lable: "obj0" }],
      obj: {
        key0: "key0",
      },
      childArr: [0, 1, 2, 3],
      childObjArr: [{ id: "0", lable: "obj0" }],
    };
  },
  watch: {
    arr() {
      alert("监听数组push");
    },
    objArr() {
      alert("监听对象数组push");
    },
    obj() {
      alert("检测到属性发生变化");
    },
    childArr() {
      alert("监听传递给子级数组的push");
    },
    childObjArr() {
      alert("监听传递给子级对象数组push");
    },
  },
  methods: {
    addNumberArr() {
      this.arr.push(this.arr.length);
    },
    deleteNumberArr() {
      this.arr.splice(this.arr.length - 1, 1);
    },
    updateNumberArr() {
      this.arr[this.arr.length - 1] = "update";
    },
    updateNumberArrBySet() {
      // let len = this.arr.length - 1;
      this.$set(this.arr, this.arr.length - 1, "$set");
    },
    addNumberArrBySet() {
      this.$set(this.arr, this.arr.length, "$set-add");
    },
    addObjectArr() {
      this.objArr.push({
        id: this.objArr.length,
        lable: `obj${this.objArr.length}`,
      });
    },
    deleteObjectArr() {
      this.objArr.splice(this.objArr.length - 1, 1);
    },
    updateObjectArr() {
      this.objArr[this.objArr.length - 1].lable = "test";
    },
    addObjectAttribute() {
      this.obj.key1 = "key1";
    },
    deleteObjectAttribute() {
      delete this.obj.key1;
    },
    updateObjectAttribute() {
      this.obj.key1 = "demo";
    },
    addChildNumberArr() {
      this.childArr.push(this.childArr.length);
    },
    deleteChildNumberArr() {
      this.childArr.splice(this.childArr.length - 1, 1);
    },
    updateChildNumberArr() {
      this.childArr[this.childArr.length - 1] = "update";
    },
    addChildObjectArr() {
      this.childObjArr.push({
        id: this.childObjArr.length,
        lable: `obj${this.childObjArr.length}`,
      });
    },
    deleteChildObjectArr() {
      this.childObjArr.splice(this.childObjArr.length - 1, 1);
    },
    updateChildObjectArr() {
      this.childObjArr[this.childObjArr.length - 1].lable = "test";
    },
  },
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style lang="scss">
h3 {
  margin: 40px 0 0;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  display: inline-block;
  margin: 0 10px;
}
a {
  color: #42b983;
}
</style>

//WatchChild.vue
<template>
  <div>
    <h2>监听父级传递过来的数字数组</h2>
    <ul>
      <li
        v-for="item in arr"
        :key="item"
      >{{item}}</li>
    </ul>
    <h2>监听父级传递过来的对象数组</h2>
    <ul>
      <li
        v-for="item in objArr"
        :key="item.id"
      >{{item.lable}}</li>
    </ul>
  </div>
</template>
<script>
export default {
  name: "watch-child",
  props: {
    arr: Array,
    objArr: Array,
  },
  watch: {
    arr() {
      alert("子级中监听父级普通数组的操作");
    },
    objArr() {
      alert("子级中监听父级对象数组的操作");
    },
  },
};
</script>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值