When it's necessary to react to a change of state in a more generic way, we can use Vue's watchers. They work quite well for most data structures, but it can cause some confusion when you're watching arrays or objects with nested properties. For example:

export default {
	data() {
    	return {
        	price: 100.0
        }
    },
    watch: {
    	price: function (newPreco, oldPrice) {
        	// whenever the car price changes, this function will be executed
        }
    }
}

In this case, since price is a simple number, everytime it changes somewhere in the component, the function price inside the watch block will be executed. Now, let's say the price we want to keep watching is inside an object, like in the following example:

export default {
	data() {
    	return {
        	car: {
                color: 'black',
        		price: 100.0
            }
        }
    },
    watch: {
    	car: function (newCar, oldCar) {
	        // whenever the price changes, this function will be executed
            // or will it?
        }
    }
}

Now, even change the name of the watcher to car, if the car price changes, the function won't be executed. Well, in this case Vue has a "trick up its sleeve". You can define the watcher as an object that receives a handler function and a property called deep which will watch for changes in the nested properties of the object, like this:

export default {
	data() {
    	return {
        	car: {
                color: 'black',
        		price: 100.0
            }
        }
    },
    watch: {
    	car: {
        	handler: function (newCar, oldCar) {
                // whenever the car price changes, this function will be executed
            },
            deep: true
        }
    }
}

Now, every time the car price changes, the watcher function will run.

We solved a problem, but introduced another: if any other property in the car object changes, for instance the color, the watcher will execute that function.

For a long time I thought there wasn'' much to do regarding this. I would usually check if the newCar price was  different than oldCar price and execute whatever I needed. But thanks to a tweet, I found out there was a much much simpler way to do this:

Michael Thiessen on Twitter
“🔥 You can watch nested values directly in @vuejs by using dot notation as a string. This avoids watching an object deeply and ignoring everything but one specific value. It also communicates your intent better because you don’t *actually* care about the whole object.”

Yes, we can simplify the previous code like this:

export default {
	data() {
    	return {
        	car: {
                color: 'black',
        		price: 100.0
            }
        }
    },
    watch: {
    	'car.price': function (newPrice, oldPrice) {
        	// now, only when the car price changes, it will execute the function
        }
    }
}

And besides, it's clear which property you want to watch in the car object.