Basic examples
Computational properties allow us to declaratively calculate derivative values. However, in some cases, we need to perform some "side effects" when the state changes: such as changing the DOM, or modifying the state in another place based on the results of an asynchronous operation.
In the Optional API, we can use the watch option to trigger a function every time the responsive property changes.
export default { data() { return { question: '', answer: 'Questions usually contain a question mark. ;-)' } }, watch: { // Whenever the question changes, this function will be executed question(newQuestion, oldQuestion) { if (('?')) { () } } }, methods: { async getAnswer() { = 'Thinking...' try { const res = await fetch('/api') = (await ()).answer } catch (error) { = 'Error! Could not reach the API. ' + error } } } }
<p> Ask a yes/no question: <input v-model="question" /> </p> <p>{{ answer }}</p>
watch
The option also supports setting the key to use.
Separated paths:
export default { watch: { // Note: It can only be a simple path and does not support expressions. ''(newValue) { // ... } } }
Deep Listener
watch
The default is shallow: the listened property will trigger the callback function only when a new value is assigned - and changes in nested properties will not trigger. If you want to listen for all nested changes, you need a deep listener:
export default { watch: { someObject: { handler(newValue, oldValue) { // Note: In nested changes, // As long as there is no replacement object itself, // Then the `newValue` and `oldValue` are the same here }, deep: true } } }
Use with caution
Deep listening requires traversing all nested properties in the listened object, which is expensive when used in large data structures. So use it only if necessary and be careful about performance.
Listener for instant callbacks
watch
Default is lazy to execute: callbacks are executed only if the data source changes. But in some scenarios, we want to execute the callback immediately when creating the listener. For example, we want to request some initial data and then re-request the data when the relevant state changes.
We can declare the listener with an object, which hashandler
Methods andimmediate: true
Options, so that the callback function can be executed immediately:
export default { // ... watch: { question: { handler(newQuestion) { // It will be called immediately when the component instance is created }, // Force callback execution immediately immediate: true } } // ... }
The first execution of the callback function occurs whencreated
Before hook. Vue has been processed at this timedata,
computed
andmethods
options, so these properties are available on the first call.
The triggering timing of the callback
When you change the responsive state, it may trigger both Vue component updates and listener callbacks.
By default, user-created listener callbacks will be called before the Vue component is updated. This means that the DOM you accessed in the listener callback will be in the state before it was updated by Vue.
If you want to access the DOM updated by Vue in the listener callback, you need to specifyflush: 'post'
Options:
export default { // ... watch: { key: { handler() {}, flush: 'post' } } }
this.$watch()
We can also use the $watch() method of component instance to create a listener imperatively:
export default { created() { this.$watch('question', (newQuestion) => { // ... }) } }
This method is useful if you want to set up a listener under certain conditions, or just listen for content that responds to user interactions. It also allows you to stop the listener in advance.
Stop the listener
usewatch
Option or$watch()
The listener declared by the instance method will automatically stop when the host component is uninstalled. So in most scenarios, you don't need to care about how to stop it.
In a few cases, you do need to stop a listener before the component is uninstalled, and you can call it$watch()
Functions returned by the API:
const unwatch = this.$watch('foo', callback) // ...When the listener is no longer neededunwatch()
This is the end of this article about listeners and usage scenarios in Vue. For more related Vue listeners, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!