vue中,如何解决watch的新值和旧值是同样的?

1、从demo出发

先看一个简单场景缓存

<template>
    <section>
      <input  v-model="obj.a">
    </section>
</template>

<script>
export default {
  data () {
    return {
      obj: {
        a: 1
      }
    }
  },
  watch: {
    obj: {
      handler (newVal, oldVal) {
        console.log('newVal', newVal)
        console.log('oldVal', oldVal)
      },
      deep: true
    }
  }
}
</script>
复制代码

此时,咱们已经设置deep: true才能监听到obj.a的变化markdown

而在打印的结果发现新值和旧值倒是同样的函数

2、窥探源码

其实看一眼源码就明白了性能

咱们在 handler函数中增长debugger调试程序ui

原来, 其实就是赋值this

对于引用类型,spa

赋值存的是地址,地址指向堆内存存储的值debug

相信你们都懂调试

而其实,官方也说明了code

3、解决办法

那如何解决呢?

1.用watch指向监听的基本类型

<template>
    <section>
      <input  v-model="obj.a">
    </section>
</template>

<script>
export default {
  data () {
    return {
      obj: {
        a: 1
      }
    }
  },
  watch: {
    'obj.a': { // watch指向监听的基本类型
      handler (newVal, oldVal) {
        console.log('newVal', newVal)
        console.log('oldVal', oldVal)
      },
      deep: true
    }
  }
}
</script>
复制代码

这种方法,简单明了

就是把对象属性(基本类型)的做为监听对象

2.使用computed

<template>
    <section>
      <input  v-model="obj.a">
    </section>
</template>

<script>
export default {
  data () {
    return {
      obj: {
        a: 1
      }
    }
  },
  computed: {
    newObj () {
      // 对 obj 进行深拷贝
      return JSON.parse(JSON.stringify(this.obj))
    }
  },
  watch: {
    newObj: { // 监听新值
      handler (newVal, oldVal) {
        console.log('newVal', newVal)
        console.log('oldVal', oldVal)
      },
      deep: true
    }
  }
}
</script>
复制代码

这种方法利用computed缓存依赖须要监听的对象

而后又对存在对象进行一个监听,从而获取先后值的变化

总结一下:

对于以上两种方法,

方法一会比方法二更‘轻’一点,性能更加,也比较推荐

感谢阅读

相关文章
相关标签/搜索