A Look at Vues Reactive Properties_870x220

The Vue JavaScript framework is "reactive," which means it can automatically refresh your data. Learn the ways you can take advantage of this in your apps.

Modern web applications need to render data dynamically in various HTML elements. Various frameworks like jQuery, React, Angular or Vue provide specific mechanisms to address this requirement and simplify the life of a programmer with high level functionality. In particular, the Vue framework provides a Reactive mechanism to display that data, and most importantly, a mechanism to take care of automatically refreshing the UI "when needed".

This raises the question: what is meant by “when needed”? Read on to get an explanation.

How the Vue Reactivity System Works

Vue provides three kinds of properties for rendering data inside HTML elements in a so-called Reactive manner. These are:

  • Properties
  • Computed properties
  • Methods

It’s important to understand how Vue treats each one and particularly how it caches these, as it will have an impact on how often and when the functions will be called.

In this post, we'll review (via a sample) how to use data properties, computed properties and methods, as well as the differences between each one of them in terms of caching.

To follow along, just download this HTML file from Github. This sample is self-contained (It contains both the HTML and the Javascript code as well as references to all required dependencies).

Using a Data Property

The first mechanism to render data in your page is to use a data property.

In the first part of the HTML file we use two properties: startupDate and message.

<div v-bind:title="startupDate">
  A property:
  <span id="id1" style="font-weight: bold;">
    {{ message }}
  </span>
</div>

These are defined when initializing the Vue object with a data object literal like this:

data: {
  message: 'Hello Vue! - This is Vue version: ' + Vue.version,
  startupDate: new Date().toLocaleString()
}

At run-time, the <div> element will be adjusted to replace the two properties with their actual values, producing an output like this:

A property: Hello Vue! - This is Vue version: 2.5.16

At this point you could go to the browser console and enter something like: app.message = "Hi"

The output would then be changed to:

A property: Hi

This is the Reactive nature of Vue: automatically detecting that a property has changed and re-rendering the affected element. This is also called one-way data binding to indicate that the element is bound to the value of a property. It’s bound one way, that is, in the direction of the Vue data towards the span with id="id1". It is not bound in the other direction. For example, if you try to change the content of that span via JavaScript, it won't change the content of the data variable.

You can check this by typing this into your console:

document.getElementById("id1").textContent = "abc"
app.message  // verify message has not changed

Interestingly, you can also bind an HTML element to a data property using JavaScript as long as you do it before the Vue object is created. This is what we do to span id="id2" with this code:

document.getElementById("id2").textContent = "{{ message }}";

Using Computed Properties

The second way to render some data is to use computed properties. You use it exactly like a data property. For example:

<span id="id3" style="font-weight: bold;">{{ computedProp }}</span>

Its definition is different though: the property is defined as a function in the object literal computed of the Vue object. For example:

computed: {
  computedProp: function () {
    // `this` points to the app instance
    return "App startup time: " + this.startupDate +
      " - Execution time: " + new Date().toLocaleString() +
      " - Dependency: " + this.dependency;
  }
}

This produces the following output:

Computed property: App startup time: 5/18/2018, 4:20:42 PM - Execution time: 5/18/2018, 4:20:42 PM - Dependency: I'm dependency property 

The second date and time is computed at function execution time. On initial display, the two dates and times are identical because the Vue object creation time and the rendering happened at about the same time.

What is interesting is that a computed property can be executed again if one of its dependencies has changed. This is exactly what happens when we click on the button "Update Dependency." Now we get some output where the two dates and times are different:

Computed property: App startup time: 5/18/2018, 4:20:42 PM - Execution time: 5/18/2018, 4:34:04 PM - Dependency: New value 1 for dependency property 

Here is what happens:

  1. computedProp is dependent on the data property, dependency
  2. When clicking the update button, an event handler changes the value of property, dependency
  3. Vue detects that the dependency data property has changed, check its list of dependents for this property and finds computedProp is a dependent. As a consequence it executes the computed property again.

Using Methods

The third way to render some data is to output the result of a function call in a method.

A method is defined in the Vue object in the methods object literal. For example:

methods: {
  computedMessageFct: function () {
    return new Date().toLocaleString();
  }
}

We use it like this:

<span id="id4" style="font-weight: bold;">{{ computedMessageFct() }}</span>

Notice the () operator to invoke the function.

When you render the sample page, properties.html, you will notice that span id="id4" gets updated every second. That's weird — we do not make additional calls to this function. Hmm, what's going on?

The reason it is updated every second is that the function computedMessageFct is invoked every time the UI re-renders independently of dependencies. In our case, it's been invoked every second because the clock property is causing a UI update every second. In other words, even though computedMessageFct is not dependent on other properties Vue still considers that <span id="id4"> needs to be refreshed, with the result of calling the function another time.

Conclusion

It's important to be aware that a computed property function can be invoked multiple times, and to pay attention to the side effects or performance implications this may have. Luckily for us, the Vue framework caches the results of these function calls and will only invoke the computed property if one of its dependency has changed.

However, this is not the case for methods used for output to HTML elements. They will be invoked again whenever the UI needs re-rendering. So be careful with the kind of computation you do in these functions. We might think we should just use computed properties then and avoid methods, but one of the advantage of methods compared to computed properties is that we can pass parameters. Once aware of the pros and cons of each type, you can choose the path you need for your applications.

And if you're working with Vue, don't forget to check out Kendo UI for Vue, our UI component library that will help you build beautiful Vue apps fast.

Editor's Note: This post originally appeared on the Progress blog. Check it out for other great content on developing your business apps.


thierry-ciot
About the Author

Thierry Ciot

Thierry Ciot is a Software Architect at Progress with a broad experience in the development of products ranging from development tools to production monitoring systems. He uses his expertise to create a low-code/rapid application development platform that provides a “Yes!” user experience. Thierry is now focusing on responsive and adaptive modern web applications. He holds two patents in the memory management space.

Related Posts

Comments

Comments are disabled in preview mode.