Vue.js: When to use methods, computed properties, or watchers

 Vue.js is reactive

That means it is able to react to things like user input and data changes. I recommend reading up on the reactivity system to have a better understanding of the mechanics Vue is using under the hood when a data change is observed. There are three main ways to have your components make use of Vue’s reactive nature. These are MethodsComputed Properties and Watchers. Without some scrutiny, these options may seem interchangeable (and in some ways they are) but each of them has their best use case scenario. To help illustrate the examples, I will make a small grading app that allows a teacher to input test scores for students in their class, view the average grade and set up the scaffolding for an auto-save feature.

Methods

tl;dr – Use methods when you want to alter a component’s state or when an event has occurred that isn’t necessarily related to the instance data being mutated. Methods can take arguments but do not keep track of any dependencies. When you use a method, it usually creates some side effect within the component and methods are ran each time the component is reloaded. This means if the UI is updated very frequently, this method (and any other methods on the component) will run as well. This could cause performance issues or lag in the UI.

Below is the beginning of our grading app. There is no validation or anything and its not pretty, I know. We have a small set of tests in our data object (student name and score). And a method we can use to add another test object to our data property ‘tests’.

 

Computed Properties

tl;dr – Use a computed property when you want to mutate a property that is dependent upon another property being changed. Computed properties are typically dependent on other data properties. Any change to the dependent properties will trigger the logic for the computed property. Computed properties are cached based on their dependencies so they will only rerun if a dependency changes. (For example, a computed property that returns a new Date() will never rerun because the logic will never run more than 1 time) Computed properties are getters by default but a setter function can be set if needed to achieve similar functionality.

In our grading app we want to keep track of the average test score as we enter more data. Lets add a computed property called ‘average’ that will return the average score of the tests in our dataset. The ‘average’ computed property will be updated any time we add another test score.

Watchers

tl;dr – Use watchers when you need to be perform some logic as a result of a change that took place on a specific data property. Watched properties only act on one property. This is most useful when you want to perform asynchronous or expensive operations in response to changing data. Keep in mind watchers only change when that specific data property changes. 

Lets pretend the end user of our little grading app is a professor with 300 tests to grade. That can take a long time. An auto-save feature would be nice to have in case our end user gets to the end of the pile of tests and forgets to manually hit save. In our code lets add a watcher to our previously created computed property ‘average’. Whenever it is changed (as a result of a new test score being added and the average being updated) lets call a new ‘autosave’ method that could be used to call an API and save our test scores.

And thats it! We have seen some use cases for some of the core reactivity features Vue.js has to offer while building our grading app. Have some other use cases or explanations? I’d love to hear them so please leave a comment!

7 things you should know about Vue.js

Get to know the rising star

Vue.js is a popular JavaScript framework that has seen a lot of success in the past couple of years. While it has gotten a lot of traction in the international development world, it is still gaining traction in the west and is not yet a household name. But I think it should be! That’s why I put together 7 things you should know about Vue.js.

 1) Its easy to learn

The first thing a newcomer to Vue.js will notice is how easy it is to pick up. Getting started with Vue only requires a few lines of JavaScript and some HTML. The technologies and concepts required to get started offer a very low barrier to entry. You can use a compiler and advanced JavaScript features (and there is an official CLI) but Vue does not enforce the use of a compiler whatsoever.  All you need to know is a few basic web technologies and you will be making awesome stuff in no time.

2) It uses a virtual DOM

You have likely heard of the concept of a virtual DOM. If you haven’t, a virtual DOM is essentially an abstract version of the real HTML DOM represented as a JavaScript object. Working directly with the DOM is easy but its not necessarily fast, especially if you have to traverse a large set of markup to make a change. Virtual DOMs allow for speedier updates to the UI.  Vue’s virtual DOM implementation (a fork of snabdom)  is very lightweight and adds very little overhead to the overall size of Vue.

3) Its fast

Like most modern front-end JavaScript frameworks these days, Vue is fast. ‘How fast?’, you ask. This article on medium and the official docs have detailed write ups of Vue’s performance compared to other popular front end frameworks like React and Angular 2. Vue gets its speed primarily by how it utilizes the virtual DOM to make changes to the UI. For example, in React, when a component requires an update, the component and any child components get updated. This can be troublesome if there are nested components and a change occurs at the root. All of the sub-components will get redrawn. When a Vue component requires an update, instead of repainting an entire component (and subsequent child components), only the changed elements/data properties get updated, thus minimizing a potentially expensive UI update operation.

4) It uses components

Get ready for some buzz words. Vue provides reactive components as a key feature of the library. You can think of components like custom HTML elements that a Vue instance attaches data and behavior to. Components can be nested within other components and reused throughout your application. There are also several ways to create components including using the component constructor: Vue.component() or the use of the <template> tag and single file components. The first two options do not require any kind of build/transpilation step in your development process but the third does. Single file components (housed in .vue files) offer several benefits including component-scoped CSS and the ability to use ES6+ features.

5) There is an official CLI to get you up and running

While the use of a compiler is completely optional, a CLI is offered by the Vue team to help get developers up and running quickly with a modern development environment. The Vue CLI comes with different template options including variations of Webpack and Browserify. The Vue CLI is great for quickly scaffolding applications without any extra boilerplate configuration.

6) There is a thriving community

At the time of writing this, Vue has over 49k stars on github and still gaining traction.  There is also a popular forum, international conference and plenty of resources related to Vue. The creator of Vue.js, Evan You is also very active in the Vue community.

7) Its battle proven

In regards to enterprise usage, Vue is popular abroad with big names in China such as Baidu and Alibaba that use Vue in different capacities. In the western world Gitlab, Laravel and recently Codeship have also adopted Vue for several projects. Success in the modern JavaScript world can be fleeting but so far we haven’t seen a plateau or drop in the popularity of Vue.

Honorable mention: Optional use of JSX

To be honest, I am not a fan of JSX. It was one of the things that turned me off from React. But several good developers I know do enjoy using JSX and are completely content with how pervasive the use of JSX is in the React community. Before I continue, let me point out that JSX is optional in React and the use of templates is available as well. If you are unfamiliar with JSX, it is basically an XML/HTML syntax used in JavaScript functions to render out markup. And while even Vue’s official documentation recommends the use of templates in Vue, I wanted to point out that render functions and JSX syntax (with the help of a transpiler) are available in case they are needed.

Hopefully these 7 facts have helped you get a better idea of what Vue is, its position in the modern JavaScript ecosystem and where its going in the future.

Form Validation with Vue.js

No one likes filling out forms

And it shouldn’t come as a shock. Forms suck and everyone knows it. Filling out a form requires end users to use their brains and recall or create data on the spot. But until we can hook up our brains to the internet, by jamming a big spike into our heads like The Matrix, we are stuck using our perfectly good fingers to input data into little rectangles and hitting the submit button.

We may not be able to get away from using forms as a data collection method, but we can at least make the process a little less painful. One way to do that is to make forms easier for the end user to complete. Properly designing a form and making forms as slim as possible are no-brainers. But what about input validation?

Client-side validation serves many purposes

Maintains data integrity – Your back end usually expects data in a particular shape. Allowing a user to post incomplete or incorrect data can cause unexpected errors in your server code.

Helps guard against malicious users – Validating your inputs before you send them off to your server can help guard against malicious users on the internet who want to commit nefarious deeds against your application. You will notice I say it helps because it really is not a good barrier against most attacks but can help defend against some attacks like SQL injection.

Creates a better user experience – This is probably the best reason to do form validation. When a user enters something into an input field incorrectly, they would rather see a helpful bit of feedback pointing to what caused the error over nothing at all. Not providing useful validation messages can lead to an overall poor user experience.

Ideally, you would have both server side data validation and client side data validation. Don’t forget that client side validation can be completely bypassed and using client side validation only is a BAD IDEA. But I still  recommend using it if for no other reason than to provide a better end user experience.

Lets see some code

I am going to be using bulma and VeeValidate in this example. Below is the markup for a small form with a text, number and email input and the Vue instance that will attach to the ‘app’ div.

In order to start using VeeValidate we need to reference the plugin via the CDN (here) and make sure Vue uses the plugin by adding a Vue.use() statement before our Vue instance is created.


Vue.use(VeeValidate);
var app = new Vue({
    el: "#app",
    data: {
        textField: "",
        numberField: "",
        emailField: ""
    },
    methods: {
        submitForm: function (e) {
            e.preventDefault();
            //post my data to my cool API without any validation! 
        }
    }
});

Next we need to add a directive to the inputs we want to listen to for input errors. Add a v-validate="" directive followed by the rules you want to apply to the input. The directive takes in a | delimited string of all the rules to be used for that input. In my form, I want my number field to be required, only allow a number between 18 and 99 and only allow 2 digits max.

With the directive on the input, VeeValidate attaches a private validator object to the vue instance and exposes a public errors object. To get the error messages generated by VeeValidate, we can use the errors.has(‘fieldName’) method (which returns a boolean) to check if there are any errors associated with the input field in conjunction with Vue’s built in v-show directive to render the error messages for the errors that have been detected. To access the error message itself, we use the errors.first(‘fieldName’) method to retrieve the first error message for that input and output that message in a span. (If you decide to show all errors that have been detected with a particular input, you can use errors.collect(‘fieldName’) to display them)

Now, if the user violates the rules we have imposed on the number field, they will get a handy red message telling them they have made a mistake.

Showing the error is great, but that message is showing the actual field name. Its normal to have a field name that is not display-worthy, but we need to have the field name on the input for VeeValidate to work. Luckily VeeValidate provides us a way to alias a field name and use that in the error message instead. It is the data-vv-as="Friendly field name" attribute.

Now the user sees an easier to understand error message.

One final bit of validation I am going to use happens when the form is submitted. VeeValidate will pick up all the errors a user has generated but it won’t do you any good if the user can still post the bad data. On button click, lets capture the submit event and check for any errors before we allow the data to be submitted. At that point you may want to throw an alert that tells the user they cannot submit the data until the errors have been corrected or highlight the fields again that contain errors.


Vue.use(VeeValidate);
    var app = new Vue({
        el: "#app",
        data: {
            textField: "",
            numberField: "",
            emailField: ""
        },
        methods: {
            submitForm: function (e) {
                e.preventDefault();
                if(this.errors.all().length > 0){
                    //do something to alert the user to the errors
                    return false;
                }
                //post my data to my cool API without any validation! 
            }
        }
    });

And although we have technically created another barrier to entry for our users, it is a necessary one that will make their experience with our products better overall.