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緩存依賴須要監聽的對象

而後又對存在對象進行一個監聽,從而獲取先後值的變化

總結一下:

對於以上兩種方法,

方法一會比方法二更‘輕’一點,性能更加,也比較推薦

感謝閱讀

相關文章
相關標籤/搜索