Vue instance properties: methods, computed and watch

methods

Methods properties are functions related to the Vue instance. “Methods” are used when you want something to execute after an event or when you want the function to execute whenever the instance / component state changes after which the DOM is re-rendered. “Methods” are also executed each time an instance (component) is loaded.

When this data changes, the view will re-render. The invocation method will always run the function whenever a re-rendering happens.
Vue.js documentation

This method behavior is enabled by the fact that Vue.js does not take into account what is within the method, so the method will be recalculated even if the change does not affect the method.

Example

In this example, we have two methods (“notification ()” and “printsValueB ()”) whose functionality is simple and described by the name of the method itself. However, the functionality that is important in this example is printing a message in the console each time any button is clicked.
The first thing to pay attention to is the fact that messages from both methods are printed immediately after loading the Vue instance in the console, which confirms the fact that the methods are executed every time the Vue instance (component) is loaded.
Then the console should be monitored after every click on the action button, because after each click two new messages are printed, no matter which button is clicked. This indicates that both methods are executed each time the DOM is re-rendered after changing one of the data properties, and even a method that is not affected by the change in the data property.

HTML

<div id = "app">
         <h4> Calling methods after re-rendering </h4>
     <p> {{notification ()}} </p>
     <Div>
             <button v-on: click = "a ++"> Increase A by one </button> <span> A = {{a}} </span>
     </ Div>
     <Div>
         <button v-on: click = "b ++"> Increase B by one </button> <span> B = {{printoutsB ()}} </span>
     </ Div>
     <p class = "note"> NOTE: <br> Check the console before use and after every click! </p>
</div>

SCSS

#app {
    padding:2rem;
    width:30rem;
    margin: 0 auto;
    text-align:center;
    button{
        margin:1rem;
    }
    span{
        margin:3rem;
    }
    .napomena{
        background-color:red;
        color:white;
        padding:1rem
    }
}

Babel

new Vue ({
     el: '#app',
     data: {
         a: 0,
         b: 0,
         c: 0
     },
     methods: {
         notification: function () {
             console.log ('Notification method executed');
             return "notification () method executed";
         },
         printoutsB value: function () {
             console.log ('The' printoutsB value 'method was executed);
             return this.b;
         }
     }
});

Conclusion:
Therefore, because of all the above, it should be emphasized that in case of frequent updating of the user interface, there may be problems with the performance of the application, since resources are consumed when restarting all methods. For example, if we have an application that displays a timer that is updated after every second, all functions in the object’s “methods” box will be called for execution after every second, and recalculated regardless of their purpose. In this case, the recommendation is to use computed properties.

computed

Computed properties are very useful for manipulating existing data, and they always have to return a value, so the name of such a function becomes a property that we can then use in the application, just as we use a “data” property. In essence, “computed” properties are variables whose values depend on other factors and will not be recalculated unless the dependencies change. Which implies that the function will use its already calculated (so-called cached) value, as long as there is no change in dependency.
Computed properties are not intended for storing data, moreover, if the “computed” property returns an object, it will always be a new object, not a modified version of the previous one. Computed properties must be functions whose actions must be synchronous and should not have side effects.

When to use Computed properties?

Functions within the “computed” property are used whenever we have some data that we need to manipulate, transform, filter, and before using them in a template. Use “computed” properties when you want to mutate a property that depends on the change of another property being changed. Computed properties should be used as a substitute for inline expressions within a template when we have more complex logic.

Some examples of tasks that are good candidates for using computed properties are:

  • Updating a large amount of information as the user writes, such as filtering a list
  • Collecting information from the “Vuex store”
    Form validation
  • Data visualizations that change depending on what the user needs to see

Example

This example shows how to use the computed property for a large set of operations:

computed: {
     bigBudget () {
         // ... some big budget that returns the result after a while
         return 2
     }
}

Now the result of these “difficult” calculations can be used over and over again in other operations without fear of recalculation if need be (if they have not changed:

methods: {
     simpleBudget (input) {
         return input * this.largeBudget
     }
}

Do you use the “computed” or “methods” property?

I will try to explain this dilemma through an example where although we use different properties, we get the same ultimate functionality.

Method

<div id="example">
  <p>Original message: "{{ message }}"</p>
  <p>Reversed message: "{{ reversedMessage() }}"</p>
</div>
 
<script>
    var vm = new Vue({
        el: '#example',
        data: {
            message: 'Hello'
        },
        methods: {
          reversedMessage: function () {
            return this.message.split('').reverse().join('')
          }
        }
    })
</script>

Computed

<div id="example">
  <p>Original message: "{{ message }}"</p>
  <p>Reversed message: "{{ reversedMessage }}"</p>
</div>
 
<script>
    var vm = new Vue({
        el: '#example',
        data: {
            message: 'Hello'
        },
        computed: {
            reversedMessage: function () {
                return this.message.split('').reverse().join('')
            }
        }
    })
</script>

The end result is the same, but that does not mean that there is no difference. The function within “methods” will be executed every time the page is rendered, every possible change of the DOM (not just changing the “messages” property), while using the computed property Vue remembers the value of the property on which the computed property depends (messages) and calculates the computed property only if the dependency changes, in every other case it returns the cached value.

Conclude:
If the logic of our application has “heavy” calculations and does not require recalculating the property each time the page is rendered, the “computed” property should be used (because we get on performance because of caching). However, if logic requires recalculation every time a page is rendered, any change (not just a dependency change), then use “methods”.

REMARK:
If the computed property is used within double curly brackets, that is, if JavaScript expressions are interpolated, then only the name of the “computed” property is specified (without the brackets denoting function invocation and execution)
e.g., {{someoneComputedProperty}}
This is another similarity to the “data” property because the “computed” property always returns some value, so practically we expect the prepared (cached) value to be printed at the interpolation site.

watch

The watch property provides an additional level of control, and allows us to track changes in the model (data). Functions within a watch object are activated only when a particular property within the data object changes. It should be emphasized that the “watched” property can only track changes on one property.

new Vue({
  el: '#demo',
  data: {
    firstName: 'Foo',
    lastName: 'Bar',
    fullName: 'Foo Bar'
  },
  watch: {
    firstName: function (val) {
      this.fullName = val + ' ' + this.lastName
    }
  }
})

REMARK:
The name of the watcher must be the same as the name of the data property whose change it is following. The changed value of the data property we are “monitoring” is passed through the watch function parameter

Deep watch

In order to track the nested (nested) properties of an object, we need to define the value of the parameter “deep” to “true”:

watch: {
    someProperty: {
      handler: function () {
        ...
      },
      deep: true
    }
}

When to use watch property?

Watch features are more specific than computed properties and thus have a narrower field of action and are less commonly used. Use them when you need to execute logic after changing a specific child property within a “data” object, with the desired action being:

  • asynchronous operation
  • the so-called budget intermediate results
  • further reducing the number of activations of certain operations (eg debounce over input event)

In addition to the mentioned cases, we can apply watch to many other functionalities, but this should be well evaluated, because although performing some functionality with a watch property is not feasible, it does not mean that it is advisable, since it can be more complicated than using a computed property. The conclusion is that the watch property should only be used when the “computed” properties cannot solve your problem.

Example

This example illustrates a situation where we cannot solve the problem with a “computed” property. One of the reasons to use the watch property in this example is to perform an asynchronous operation inside it, and the other is to define an answer until a final answer is obtained. None of these tasks could be done with the “computed” property.

new Vue ({
   el: '# watch-example',
   data: {
     question: '',
     answer: 'I can't give you an answer until you ask a question!'
   },
   watch: {
     question: function (newQuestion, oldQuestion) {
       this.answer = 'Waiting for you to stop typing ...'
       this.nekiAsinhroniZahtev ()
     }
   },
 
   . . .
 
})

Example

In this example, we use the “searchQuery” property to track the change of the data property of the same name, after which we make an asynchronous request to the server:

HTML

<div id = "app">
   <input type = "text" v-model = "searchQuery" placeholder = "Enter search text">
  
   <p v-if = "isSearching"> Searching ... </p>
   <div v-else>
     <ol>
       <li v-for = "result in results"> {{result}} </li>
     </ol>
   </div>
</div>

SCSS

#app {
    padding:2rem;
}

Babel

new Vue ({
     el: '#app',
   data: {
     searchQuery: '',
     results: [],
     isSearching: false
   },
   watch: {
     searchQuery: function (query) {
       this.isSearching = true;
       var vm = this;
       // Imitate asynchronous server call
       setTimeout (function () {
         vm.results = ['JavaScript', 'PHP', 'MySQL'];
                 vm.isSearching = false;
       }, 2000);
     }
   }
});

Application through example

Through this example, I will try to explain the application of each of these important properties.

var vm = new Vue({
    el: '#welcome',
    data: {
        message: 'Hello',
        name: 'World',
        nameEdits: 0
    },
    methods: {
        numRenders: function () {
            console.log('Page rendered')
        }
    },
    computed: {
        welcomeMessage: function () {
            return this.message + ' ' + this.name
        }
    },
    watch: {
        name: function () {
            if (this.message.toLowerCase() === 'reset') {
                this.nameEdits = 0
            } else {
                this.nameEdits += 1
            }
        }
    }
})

a) methods section
The “numRenders” function from the “methods” section will be called with each render. So whenever anything is updated on the UI, the “numRenders” function is called.

b) computed section
In the “computed” section, welcomeMessage will only be called when the “message” or “name” is changed, because it depends on these two things. So, if any of the other variables like “nameEdits” are changed, “welcomeMessage” our function in the “computed” section will not be called again because it does not depend on them.

c) watch section
The “name” function in the “watch” section only tracks changes to the “name” value from the “data” object. This means that whenever “name” is changed, our function is called to update and change the nameEdits value. If any of the other variables in the “data” object “nameEdits” or “message” are changed, our function u will not be called again because it does not follow them.

Likes:
15 0
Views:
1694
Article Categories:
PROGRAMMINGTECHNOLOGY

Leave a Reply

Your email address will not be published. Required fields are marked *