Watch Nested Component Data with VueJS
There are multiple times where you need to watch pieces of data within your VueJS component. However, did you know you can watch nested component data with VueJS? Let’s say you are mapping a data to a model that looks like this:
export default {
data(){
return {
form: {
name: '',
dob: '',
job: ''
}
}
}
}
This is a nice way to handle sending data to an API since all you have to do is pass this.form
. However, what if you want to compute values when a piece of the nested data changes or if the whole form changes? Luckily VueJS makes that a breeze. Let’s run through a few examples.
Watching A Single Piece of Component Data
Let’s say we want to check to see if the user is over 18 before they are applying for a job. We would need to watch the dob
field in the form
object. To do that, we can add a watcher to our component like this:
export default {
data(){
return {
form: {
name: '',
dob: '',
job: ''
}
}
},
watch: {
'form.dob': function(){
// perform age calculation
}
}
}
VueJS allows us to watch a nested object using the ‘.’ notation syntax.
Watching the Whole Component Data Object
Now, let’s say we want to watch for any changes in the entire form which is a piece of component data. This could be useful if we are determining if the user entered any information and tries to navigate away. We can then prompt them to leave the page.
Within VueJS, you can set up your watcher like this:
export default {
data(){
return {
form: {
name: '',
dob: '',
job: ''
}
}
},
watch: {
'form': {
deep: true,
handler(){
// flag that the user made changes
}
}
}
}
When you set up your watch
this way, you can pass the deep
option and set it to true. This will monitor any of the changes on the form object itself. Then we pass the handler()
function which will actually perform a method when triggered. In this case, we will set a flag or raise an event notifying that the user made a change. This will allow us to notify them before they try to leave the page.
Watching a Vuex Store
You can also watch a Vuex Store. Let’s assume that we have a Vuex module that contains our form. We can still monitor for any changes to the state and perform the same functionality:
import { mapState } from 'vuex';
export default {
computed: {
...mapState('form', {
'form': state => state.form
})
}
watch: {
'form': {
deep: true,
handler(){
// flag that the user made changes
}
}
}
}
This is super convenient if you are sharing data between components and you want to watch if a piece of state has changed on another component. I tend to use this exact functionality when dividing up a large page form into multiple parts. For example, I’ve watched for address fields and when I have all of the information, submitted a request to Google for geocoding.
As always, reach out if you have any questions or need more information!