vue3: new value and old value returned by deep watcher always same

Viewed 1864

const app = {
  data(){
    return {
      form: {
        name: '',
        password: ''
      }
    } 
  },
  watch: {
    form: {
      handler(form, oldForm){
        console.log(form, oldForm);
      },
      deep: true
    } 
  }
}

Vue.createApp(app).mount('#app')
<script src="https://unpkg.com/vue@next"></script>
<main id="app">
  <form>
    <input v-model="form.name"/>
    <input v-model="form.password"/>
  </form>
</main>

I got a deep watcher for an object value, accroding to the document, it should get both the previous and current value of the object been watched.

But in this code, the new value and the old value returned by the deep watcher are always same. Why is that?

Thanks a lot for anyone help!

2 Answers

Ref: watch

Note: when mutating (rather than replacing) an Object or an Array and watch with deep option, the old value will be the same as new value because they reference the same Object/Array. Vue doesn't keep a copy of the pre-mutate value.

Use setup to watch instead...

import {reactive} from 'vue'

setup() {
  const form = reactive({
      name: '',
      password: ''
  })

  watch(
        () => ({ ...form }),
        (newVal, oldVal) => {
            console.log('Form changed', newVal, oldVal)
        }
    )

  return {
    form
  }
}

Related