This is one of the most frequently asked questions in an interview for a VUE development position

What is the role of computed in VUE? Take a simple example 🌰

<div id="app">
    {{message}}
   <div>computed  {{getMessage}}</div>
</div>
Copy the code
var app = new Vue({ el: '#app', data: { message: 1, }, computed: { getMessage: function(){ return this.message * 2; }}});Copy the code

The result is displayed

1
computed 2
Copy the code

Computed by using this. Message to call the message value in data in vue multiplied by 2(this refers to the app instance), the result of the getMessage method renturn, shown here in the template engine using the {{getMessage}} call, The getMessage function is declared as a getMessage property of the app. App.getmessage returns 2 in the console, where we type

app.message = 2;
consoe.log(app.getMessage) //4
Copy the code

The value of getMessage in computed is affected by app.message

Contrast computed with methods

The above calculated attributes can also be realized in methods.

<div id="app">
    {{message}}
   <div>methods  {{getMessage()}}</div>
</div>
Copy the code
var app = new Vue({ el: '#app', data: { message: 1, }, methods: { getMessage: function(){ return this.message * 2; }}});Copy the code

The browser also displays the result

1
methods 2
Copy the code

So if you get the same result, what’s the difference between these two things, and why use computed? With that in mind, let’s go into detail.

Computed properties are cached based on their reactive dependencies

That is, in computed, the value of getMessage changes according to the message in data. If the Message in data is not called in getMessage, getMessage will not be computed, official 🌰

computed: {
  now: function () {
    return Date.now()
  }
}
Copy the code

No matter how many times we call now, it will always be the first calculated time, because date.now () is not reactive, so we’ll change the example from the official website

computed: {
  now: function () {
    console.log(this.message);
    return Date.now()
  }
}
Copy the code

We print message without returning anything, and we make changes to app.message in the browser console,

app.message = 2;
Copy the code

At this time, the value of NOW is also updated, which indicates that as long as message is added to computed, a responsive relationship is established between computed and now. When app. Message is updated, now is also updated, and the corresponding cache method now is also updated. To reduce performance overhead and avoid repeated calls to getter methods, we try to use computed caching, and if we don’t need caching, we use methods directly in Methods.

The computed and watch

Watch is provided in VUE to listen for attribute changes in vUE instances, so how is it different from computed?

Let’s start with an example

 var app = new Vue({
    el: '#app',
    data: {
        firstName: {
            a: 'Foo'
        },
        lastName: 'Bar',
        fullName: 'Foo Bar'
    },
    computed: {
        first(){
            return this.firstName;
        },
        full(){
            return this.firstName.a +' '+this.lastName
        }
    },
    watch: {
        firstName: function (val) {
            this.fullName = val.a + ' ' + this.lastName
        },
        lastName: function (val) {
            this.fullName = this.firstName.a + ' ' + val
        }
    }
  });
Copy the code

Watch and computed, firstName lastName fullName in data, and notice that firstName is an object with a child property,

<div id="app">
  <div>data.firestName - firstName {{firstName.a}}</div>
  <div>watch - fullName {{fullName}}</div>
  <div>computed - {{first.a}}</div>
  <div>computed - {{full}}</div>
</div>
Copy the code

Default browser display

data.firestName - firstName Foo
watch - fullName Foo Bar
computed - Foo
computed - Foo Bar
Copy the code

At this point, we type app.firstname. a =’hello’ on the browser console and get the following result:

data.firestName - firstName hello
watch - fullName Foo Bar
computed - hello
computed - hello Bar
Copy the code

We found that the firstNam monitored in Watch did not play a role and the fullname value was not updated. Can’t Watch be used? I tried app.lastName = ‘word’ in the browser and got an update:

data.firestName - firstName hello
watch - fullName hello word
computed - hello
computed - hello word
Copy the code

Comparison of computed and watch

1. Watch cannot deeply monitor object properties. If watch needs to implement deep monitoring, it needs to add option deep: true (default is false).

2. For watch, you can directly set the data value without return. For computed, you need return to invoke the value

3. For computed, by default, there are only getter methods. If you want to assign values to computed, you need to define setter methods; otherwise, the browser will report an error

4. Watch can also perform asynchronous operations and call methods of other libraries according to a property change, which cannot be realized in computed

The way that computed setters are defined

computed: { fullName: { // getter get: function () { return this.firstName + ' ' + this.lastName }, // setter set: function (newValue) { var names = newValue.split(' ') this.firstName = names[0] this.lastName = names[names.length - 1] }}}Copy the code