watch监听不到变化?

watch监听不到对象内部的变化

有的时候vue会出现这种现象,无法监听到复杂对象内部的变化:当对象里面原本有某一个属性,并对这个属性操作时,watch是可以监听到当前属性的变化的。但是,若对象里面本没有这个属性的时候,在操作时将属性添加进去,同时包括之后对这个属性的操作,watch是都检测不到的。

这是因为vue的watch会在初始化的时候通过object.defineProperty给对象的每一个属性都添加watcher来监听内部的变化。所以,后期添加上去的属性是无法检测到的。

解决方法:

如果想在初始化后添加一个属性并进行监听操作,可以使用$set:

// this.$set(object, key, value)
// 使用this.$set就可以监听到
this.$set(this.obj, 'a', Math.random())
复制代码

watch的handler方法的两个参数值相同

一个数据,如果值发生了变化,如果想要记录变化前和变化后的两个值,可以使用handler方法,第一个参数为变化后的新值,第二个为变化前的旧值。

但是如果这个值是复杂对象,如果想记录里面的属性的变化,使用handler,两个参数均为变化后的新值。

解决方法:

结合计算属性、序列化、反序列化生成新的对象,来避免此问题

 data () {
    return {
      obj: {}
    }
  },
  computed: {
    // 如果想要得到差异内容,可以结合计算属性、序列化、反序列化生成新的对象,来避免此问题 。
    obj2 () {
      return JSON.parse(JSON.stringify(this.obj))
    }
  },
  watch: {
    obj2: {
      handler (newVal, oldVal) {
        console.log('data变化了')
        console.log(newVal, oldVal)
      },
      deep: true
    }
  },
复制代码

全部代码

<template>
  <div>
    <button @click="clickFn">++++</button>
  </div>
</template>

<script>
export default {
  name: 'Mall',
  data () {
    return {
      // !监听时给每一个属性都添加getter和setter,变化了,就触发handler函数,如果后期添加属性,这个属性不可以被监听到
      // obj: {
      //   a: 10
      // }

      // !这种是不可以被监听到的
      // 因为watch是通过Object.defineProperty()给对象的每一个现有属性增加监听器
      // 在后面直接添加a属性,身上没有监听器,所以不会被监听到
      obj: {}
    }
  },
  computed: {
    // 如果想要得到差异内容,可以结合计算属性、序列化、反序列化生成新的对象,来避免此问题 。
    obj2 () {
      return JSON.parse(JSON.stringify(this.obj))
    }
  },
  watch: {
    obj2: {
      handler (newVal, oldVal) {
        console.log('data变化了')
        console.log(newVal, oldVal)
      },
      deep: true
    }
  },
  methods: {
    clickFn () {
      // this.obj.a = Math.random()

      // this.$set(object, key, value)
      // 使用this.$set就可以监听到
      this.$set(this.obj, 'a', Math.random())
    }
  }
}
</script>
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Vue中的`watch`是一个响应式系统,用于监听数据的变动并执行相应的函数。然而,有时候可能会遇到`watch`监听不到数据变化的情况,这可能有以下几个原因: 1. **数据源问题**:确保你正在`watch`的数据绑定到了正确的变量或响应式属性上。如果数据是在组件之外定义的,或者使用了`v-model.lazy`这样的特殊行为,`watch`可能不会立即响应。 2. **依赖更新时机**:`watch`是异步的,特别是在首次设置时,会等到下一次数据更新循环(通常在DOM渲染后)才会开始监听。如果你期望立即生效,可以在`watch`回调中显式调用`$set`方法手动触发更新。 3. **深度监听**:默认情况下,`watch`只监听数据对象的浅层次属性。如果你需要监听嵌套对象或数组的变化,需要启用深度监听,通过在`watch`选项里添加`deep: true`。 4. **异步函数**:如果被监听数据是由异步操作返回的,那么`watch`可能无法立即捕获到变化,因为数据还没有更新。在这种情况下,你可以考虑使用`async`和`await`,或者`immediate`选项。 5. **watch生命周期问题**:`watch`不是在每个属性改变时都执行的,而是根据Vue内部的策略来调度。如果你的监听函数在其他逻辑中修改了被观察的值,可能导致预期外的结果。 6. **惰性求值**:`watch`中的函数默认是惰性求值的,这意味着它们只有在第一次执行时才会被编译。如果你在`watch`回调里创建了新的函数或引用,这些可能不会被立即更新。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码云笔记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值