Vue.js

【vue.js】watchでdeep: trueを使うとoldValueとnewValueが同じになってしまうという罠

問題点

Vue.jsのwatchでdeep: trueを使うとoldValueとnewValueが同じになってしまい、どの値が更新されたか分からない状態になってしまう。

<script>
let app = new Vue({
  data: {
    sample: {
      1: null,
      2: null,
      3: null,
      4: null
    }
  },
  watch: {
    sample: {
      deep: true,
      handler(newValue, oldValue) {
        console.log(newValue)
        console.log(oldValue)
      }
    }
  }
})
</script>

解決方法

computedで非参照のコピーを作って、そのcomputedをwatchすることで解決できる

<script>
let app = new Vue({
  data: {
    sample: {
      1: null,
      2: null,
      3: null,
      4: null
    }
  },
  computed: {
    computedSample () {
      // 非参照のコピーを作る
      return JSON.parse(JSON.stringify(this.sample))
    }
  },
  watch: {
    computedSample: {
      deep: true,
      handler(newValue, oldValue) {
        console.log(newValue)
        console.log(oldValue)
      }
    }
  }
})
</script>
ABOUT ME
ytakeuchi
都内在住のフロントエンドエンジニア。2016年からフリーランスとして活動中。座右の銘は「昨日よりも楽に」。好きな言葉は「効率化」。こんな性格なのでプライベートではGoogle Apps Scriptばかり触っています。