The difference between calculated and watch in Vue

Posted May 25, 20206 min read

We will more or less use computed and watch in the Vue project. These two seem to be able to monitor data, but there are still differences. So the following through a small chestnut to understand the difference between the two.

\ [Poke me to check the official website ]

computed calculated attribute
The calculated property is based on a new value calculated by the data declared in the data or props passed by the parent component. This new value will only change according to the change of the known value. In short:this property depends on Attributes are calculated from other attributes.

<p> Name:{{fullName}} </p>
...
data:{
    firstName:'David',
    lastName:'Beckham'
},
computed:{
    fullName:function() {//The return value of the method is used as the attribute value
            return this.firstName + '' + this.lastName
    }
}

Defining the method of calculating attributes in the computed attribute object is the same as fetching the data attributes in the data object in the form of attribute access, that is, using {{method name}} on the page to display the results of the calculation.

Note:The calculated attribute fullName cannot be defined in data, and the related known value of the calculated attribute value is in data;
If fullName is defined in data, an error will be reported as shown below:

QQ screenshot 20200525144944.png
Because if the computed attribute value is a function, then the default will go to the get method, there must be a return value, the return value of the function is the attribute value of the attribute. The calculated attribute defines fullName and returns the corresponding result to this variable. The variable cannot be defined and assigned repeatedly.

In the official document, an important feature of computed is also emphasized, that is, computed has a cache function. For example, I display fullName multiple times on the page:

<p> Name:{{fullName}} </p>
<p> Name:{{fullName}} </p>
<p> Name:{{fullName}} </p>
<p> Name:{{fullName}} </p>
<p> Name:{{fullName}} </p>
...

computed:{
    fullName:function() {
         console.log('computed') //printed only once in the console
         return this.firstName + '' + this.lastName
    }
}

We know that the function defined in the computed is only executed once, and is only called when the initial display or related data such as data and props changes;
The computed attribute value caches the calculation results by default, and the calculated attributes are cached based on their responsive dependencies;
Only when the computed attribute is used, the computed code will be executed. In repeated calls, as long as the dependent data remains unchanged, the calculation result in the cache is directly fetched. Only if dependent data changes **, computed will be recalculated.

Advanced level of calculated attributes:
The attribute in computed has a get and a set method. When the data changes, the set method is called. Next, we implement the display and monitoring of attribute data by means of the getter/setter method of calculating attributes, that is, two-way binding.

computed:{
    fullName:{
        get() {//Callback to read the current attribute value, calculate and return the current attribute value based on the relevant data
            return this.firstName + '' + this.lastName
        },
        set(val) {//Callback when the attribute value changes, update the relevant attribute data, val is the latest attribute value of fullName
            const names = val? val.split(''):[];
            this.firstName = names [0]
            this.lastName = names [1]
        }
    }
}

watch watch attribute
Through the $watch() or watch configuration of the vm object to monitor the attribute changes on the Vue instance, or the changes of some specific data, and then perform some specific business logic operations. When the property changes, the callback function is automatically called and the calculation is performed inside the function. The data sources that can be monitored:data, props, and data in the calculated.

The above example is implemented by watch:

watch:{
    //Monitor the firstName in data, if there is a change, give the changed value to the fullName in data, val is the latest value of firstName
    firstName:function(val) {
        this.fullName = val + '' + this.lastName
    },
    lastName:function(val) {
        this.fullName = this.firstName + '' + val
    }
}
//It can be seen from the above that watch should monitor two data, and the code is the same type of repetition, so it is more concise than using computed

Note: The listening function has two parameters, the first parameter is the latest value, the second parameter is the value before input, the order must be new value, old value, if only one parameter is written , That is the latest attribute value.

When you choose to use watch or computed when you use it, there is another reference point that the official website says:when you need to perform asynchronous or expensive operations when the data changes, the watch method is most useful. So watch must support asynchronous.

The above is limited to monitoring simple data types, and monitoring complex data types requires deep monitoring deep.
| deep: In order to discover changes in the internal value of the object, you can specify deep:true in the option parameters. Note that it is not necessary to do this for monitoring array changes.

data:{
    fullName:{
        firstName:'David',
        lastName:'Beckham'
    }
},
watch:{
    fullName:{
        handler(newVal, oldVal) {
            console.log(newVal);
            console.log(oldVal);
        },
        deep:true
    }
}

The above print results:
QQ screenshot 20200525162250.png
The newVal and oldVal values printed are the same, so although the deep monitor can monitor the changes of the object, it cannot monitor the changes of specific attributes in the object. This is because their references point to the same object/array. Vue will not keep a copy of the value before the change. \ [vm. $watch Deep Watch ]

If you want to monitor changes in a single property of an object, there are two methods:

  1. Directly listen to the properties of the object

    watch:{

     fullName.firstName:function(newVal, oldVal) {
         console.log(newVal, oldVal);
     }

    }

  2. Used in conjunction with the computed attribute, computed returns the attribute value you want to monitor, and watch is used to monitor

    computed:{

     firstNameChange() {
     return this.fullName.firstName
     }

    },
    watch:{

     firstNameChange() {
         console.log(this.fullName)
     }

    }

to sum up:

watch and computed are based on Vue's dependency tracking mechanism. When a certain dependent data(dependent data:simple understanding is the instance data placed under data and other objects), all dependencies The relevant data of this data will automatically change, that is, the relevant functions are automatically called to realize the data changes.
When the value of the dependency changes, some complex operations can be done in the watch, and the dependency in the calculated is only one value depends on another value, which is a value dependence.

Application scenario:
Computed:Used to process complex logical operations; a data is affected by one or more data; used to deal with situations that cannot be handled by watches and methods, or inconvenient to handle. For example, deal with the complex expressions in the template, the change relationship between the number of items in the shopping cart and the total amount, etc.
Watch:used to deal with the need to perform some specific business logic operations when a property changes, or to perform asynchronous or expensive operations when the data changes; one data change affects multiple data. For example, it is used to monitor routing, special processing of inpurt input box value, etc.

the difference:
computed

  • Called when the initial display or related data such as data, props, etc. have changed;
  • The calculated attribute is not in data, it is a new value obtained by calculation based on the data in data or props, this new value changes according to the change of the known value;
  • The method of defining the calculated attribute in the computed attribute object is the same as the data attribute in the data object, and is called in the form of attribute access;
  • If the computed attribute value is a function, then the default will go to the get method, there must be a return value, the return value of the function is the attribute value of the attribute;
  • The computed attribute value will cache the calculation result by default. In repeated calls, as long as the dependent data remains unchanged, the calculation result in the cache is directly fetched, and only dependant data occurs changes, computed Will be recalculated;
  • In computed, the property has a get and a set method, when the data changes, call the set method.

watch

  • Mainly used to monitor the changes of certain specific data, so as to carry out some specific business logic operations, can be regarded as a combination of computed and methods;
  • Sources of data that can be monitored:data, props, calculated data;
  • watch supports asynchronous;
  • Cache is not supported, changes in the monitored data will directly trigger the corresponding operation;
  • The listener function has two parameters. The first parameter is the latest value, and the second parameter is the value before input. The order must be the new value and the old value.