First, start with demo
Let’s start with a simple scenario
<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>
Copy the code
At this point, we have set deep: true to listen for changes in obj.a
In the printed result, the new value and the old value are the same
Two, peep source code
In fact, a look at the source code will understand
We added the debugger to the handler function
Turns out, it’s just assignment
For reference types,
Assignment stores addresses, which point to values stored in heap memory
I’m sure you understand
And in fact, it’s official
Third, solutions
So what’s the solution?
1. Use Watch to point to the basic type of listening
<template>
<section>
<input v-model="obj.a">
</section>
</template>
<script>
export default {
data () {
return {
obj: {
a: 1
}
}
},
watch: {
'obj.a': {// watch points to the basic type of listener
handler (newVal, oldVal) {
console.log('newVal', newVal)
console.log('oldVal', oldVal)
},
deep: true
}
}
}
</script>
Copy the code
It’s a straightforward approach
That is, the listener of an object property (primitive type)
2. The use of computed
<template>
<section>
<input v-model="obj.a">
</section>
</template>
<script>
export default {
data () {
return {
obj: {
a: 1
}
}
},
computed: {
newObj () {
// Make a deep copy of obj
return JSON.parse(JSON.stringify(this.obj))
}
},
watch: {
NewObj: {// listen for new values
handler (newVal, oldVal) {
console.log('newVal', newVal)
console.log('oldVal', oldVal)
},
deep: true
}
}
}
</script>
Copy the code
This approach uses computed caching to rely on objects to listen on
And then a listener to the existing object, so as to obtain the change of the value before and after
To sum up:
For the above two methods,
The method is a bit lighter than method 2, with better performance and is recommended
Thank you for reading