Usage Summary of watch in vue

Vue provides a more general way to observe and respond to data changes on Vue instances: listening properties.

1. General usage

<template>
    <div>
        <input v-model="question">
        <span>{{ copyQuestion }}</span>
    </div>
</template>

<script>
export default {
    data() {
        return {
            question: 'Hello World',
            copyQuestion: ''
        };
    },
    watch: {
        question: function (value) {
            this.copyQuestion = value;
        }
        // The following can be abbreviated. The key value is one, the key is question, and the value is question() method
        // question(value) {
        //     this.copyQuestion = value;
        // }
        // In addition, the following can listen for new and old values
        // question(newValue, oldValue) {
        //     .......
        // }
    }
};
</script>

Note: when using the basic usage of watch, one feature is that when the value is bound for the first time, the listening function will not be executed, and it will be executed only when the value changes.

2. Binding method

<template>
    <div>
        <input v-model="question">
        <span>{{ copyQuestion }}</span>
    </div>
</template>

<script>
export default {
    data() {
        return {
            question: 'Hello World',
            copyQuestion: ''
        };
    },
    watch: {
        // The key is question and the value is' handleQuestion() method. Every time you listen for a change in question, 'handleQuestion() method will execute once
        question: 'handleQuestion'
    },
    methods: {
        handleQuestion(value) {
            this.copyQuestion = value;
        }
    }
};
</script>

Note: the value of bidirectional binding (v-model="message" and data() {return)
{message}}) and watch listening keys should be consistent, both of which are message

3,deep + handler

When it is necessary to monitor the changes of an object, the basic watch method cannot monitor the changes of the internal attributes of the object. Only the data in data can monitor the changes. At this time, the deep attribute is required to deeply monitor the object.

Reason: due to the limitations of modern JavaScript (and the abandonment of Object.observe), Vue cannot detect the addition or deletion of object attributes. Because Vue will perform getter/setter conversion on the attribute when initializing the instance, the attribute must exist on the data object to make Vue convert it and make it responsive.

<template>
    <div>
        <input v-model="deepQuestion.a.b">
        <span>{{ copyQuestion }}</span>
    </div>
</template>

<script>
export default {
    data() {
        return {
            deepQuestion: {
                a: {
                    b: 'deep question'
                }
            },
            copyQuestion: ''
        };
    },
    watch: {
        deepQuestion: {
            handler: 'handleQuestion',
            deep: true
        }
    },
    methods: {
        handleQuestion(value) {
            this.copyQuestion = value.a.b;
        }
    }
};
</script>

By default, the watch method only listens to the objects in the data, but cannot listen to the changes of the internal attributes of the object. At this time, the deep attribute is required to deeply listen to the object. (default: deep:false)

This will only add listeners to a specific attribute of the object. Changes in arrays (one-dimensional and multi-dimensional) do not need to be monitored in depth. Changes in the properties of objects in the object array need to be monitored in depth.

Have you noticed the handler? We bound a handler method to firstName. The watch method we wrote before actually writes this handler by default, Vue JS will handle this logic, and the final compiled handler is actually this handler.

Deep means deep observation. The listener will traverse down layer by layer and add this listener to all attributes of the object, but the performance overhead will be very large. Any modification of any attribute in obj will trigger the handler in this listener. Next, we use the form of string for listening optimization.

watch: {
  'deepQuestion.a.b': {
    handler(newValue, oldValue) {
      console.log(newValue, oldValue);
    },
    immediate: true,
    // deep: true
  }
} 

When only listening to a few attribute values of an object, you can use the object Property to listen as a string.

So Vue JS will parse layer by layer until it encounters attribute b, and then set the listening function for b.

4,immediate

By default, when a page is rendered for the first time, even if the monitored value has an initial value, it will not be directly executed. In this case, if you want to directly monitor after the first rendering, you need to add the attribute: immediate: true

<template>
    <div>
        <input v-model="question">
        <span>{{ copyQuestion }}</span>
    </div>
</template>

<script>
export default {
    data() {
        return {
            question: 'hello question',
            copyQuestion: ''
        };
    },
    watch: {
        question: {
            handler: 'handleQuestion',
            immediate: true
        }
    },
    methods: {
        handleQuestion(value) {
            this.copyQuestion = value;
        }
    }
};
</script>

For example, when the parent component dynamically transfers values to the child component, the child component props also needs to execute the function when it obtains the default value from the parent component for the first time. At this time, it is necessary to set immediate to true.
The monitored data is written in the form of an object, including the handler method and immediate. The function we wrote before is actually writing the handler method.

5. Log off watch

Why log off watch? Because our components are often destroyed. For example, if we jump a route and jump from one page to another, the watch of the original page is actually useless. At this time, we should log off the watch of the original page, otherwise it may lead to built-in overflow. Fortunately, we usually write the watch in the option of the component. It will be destroyed as the component is destroyed. The above are all cases used in components.
However, if we write the watch in the following way, we have to log out manually. In fact, this kind of log out is very simple

const unWatch = app.$watch('text', (newVal, oldVal) => {
  console.log(`${newVal} : ${oldVal}`);
})

unWatch(); // Log off watch manually

app.$ After the call of watch, a value will be returned, which is the unWatch method. If you want to log out of watch, just call the unWatch method.

6. watch monitor route

    watch: {
        $route: {
            handler: function (to, from) {
                console.log(to); // To indicates the interface to
                console.log(from); // From indicates which interface it comes from
                if (to.path == '/goods/detail') {
                    console.log('Goods details');
                }
            }
        }
    }

perhaps

// Listen and execute when the route changes
watch: {
  $route: {
    handler: function(val, oldVal){
      console.log(val);
    },
    // Deep observation and monitoring
    deep: true
  }
}

perhaps

// Listen and execute when the route changes
watch: {
  '$route':'getPath'
},
methods: {
  getPath(){
    console.log(this.$route.path);
  }
}

(end)

Source code analysis: Vue.js source code analysis (VII) basic part detailed explanation of listener watch attribute

Keywords: Front-end Vue Vue.js

Added by ErcFrtz on Mon, 31 Jan 2022 07:04:35 +0200