Peeking into Vue.js 2

Alex Kyriakidis
dotdev
Published in
6 min readJun 30, 2016

--

Vue.js 2 is coming and we are all excited about it. The new Vue, along with great improvements and new features (Virtual DOM, Server Side Rendering, JSX/Hyperscript support, and more), comes with a few deprecations and conversions.

New Features

All these new features that Vue 2 comes with, sound great. Though, before you use them, you should get a bit familiar with what exactly each one is.

Virtual DOM

Virtual DOM is an abstract/lightweight version of the real DOM.

The main concept is that instead of touching the DOM directly, you touch the Virtual DOM which is being compared with the actual DOM. After the comparison, the parts of the DOM that need be to changed are being re-rendered.

It is much faster than working directly with the DOM because it doesn’t require all the heavyweight parts that go into a real DOM.

Below is an article by Tony Freed, that I believe you should read if you want to learn more about Virtual DOM.

Server Side Rendering

Except from browsers, JavaScript can be run on servers, using platforms like Node.js.

By running Javascript Server-Side, you can generate HypetText or HTML and send its content directly to client’s browser. This is typically used to avoid a flash of temporarily empty templates, caused by the browser while he is rendering the templates. (You may have seen an empty pair of ‘{{ }}’ shown, before viewing the actual content.)

Server Side Rendering usually results in much faster time-to-content and slightly slower time-to-interaction.

SSR is also useful for SEO, Facebook’s meta tags, etc.

In addition, people use SSR to build their APIs with Javascript frameworks like Meteor, Express, Sails, etc.

What I most like in SSR is that the server does more work and the client less. This is lifesaving for users who are visiting a website from an old computer or a not so powerful mobile phone.

JSX (XML-like syntax extension)

JSX is a XML-like syntax extension to ECMAScript without any defined semantics. It’s NOT intended to be implemented by engines or browsers. It’s intended to be used by various preprocessors (transpilers) to transform these tokens into standard ECMAScript.

For example:

The homepage of the JSX project is http://facebook.github.io/jsx/

Hyperscript

Hyperscript is used to create HyperText with JavaScript, on client or server.

Have a look to the below example and its output.

Heading with class=”fun”

You can play around with Hyperscript on their Interactive Demo page.

Deprecations & Changes

I am going to build a simple app using Vue 2 to point out some differences between the two versions.

The main points that I will cover are:

  • events
  • .sync modifier deprecation
  • vm.$set() method deprecation
  • component’s template wrapper
  • and a few minor changes

Goodbye .sync

One thing that we all gonna miss is the ability to synchronise data between parent and child components using the “.sync” modifier. From now on, props will always be one-way down. If a component needs to modify data outside of its scope, it has to emit an event, instead of relying on implicit binding.

The purpose behind this deprecation is to prevent child component from causing side effects in parent’s scope. This way, when you are reading a component’s code it’s much easier to understand what it does and how it affects the rest of your application.

Vue Versions Comparison

Using Vue 1.0.*

The scenario I am going to work on, is the following. We have a page where users can buy gems. There, we have a Vue instance and a Cart component. Within Cart component, the user selects how many gems wants to buy and then the component reflects that change to its parent.

Using Vue.js 1.0.* the implementation would be obvious. We would create a variable, to store the selected quantity, we would pass it to the component which would update its value and return it to parent Vue. Inside Vue, we would need a computed property to calculate the total price.

Vue.js 1.0.*

Using Vue 2

If we migrate to Vue 2, we will get the following warning, when running the above code.

[Vue warn]: Component template should contain exactly one root element.

To bypass this warning, we will enclose component’s template inside a ‘div’ element.

root element

If we refresh the browser we see that the warning is gone.

The warning we get now when we try to change the quantity, is:

[Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop’s value. Prop being mutated: “gems” (found in component: <cart>)

That is because, in Vue 2, mutating a prop locally is considered an anti-pattern. Due to the new rendering mechanism, whenever the parent component re-renders, the child component’s local changes will be overwritten. You should now treat props as immutable.

In object-oriented and functional programming, an immutable object is an object whose state cannot be modified after it is created.

So, instead of updating the ‘quantity ’ prop and syncing it with parent’s, we will make our component submit an event to the parent. It also has to watch for quantity changes, and when happens, it has to emit an event with the new value. We don’t even need a prop.

Since ‘vm.$dispatch’ andvm.$broadcasthave been deprecated, in order to fire an event we are going to use a centralised event hub that allows components to communicate, as suggested in the upgrade tips.

Because Vue instances implement the event emitter interface, we can actually use an empty Vue instance as our event emitter.

Let’s get back to our example, to create this emitter and refactor Cart component.

If you check the console, you will notice that every time you change quantity’s value you see its current and previous values.

browser’s console outpup

The only thing left, is to update the parent Vue instance to listen to this event and update it’s quantity data accordingly. To do so, we will set up an event listener within created hook.

Notice 1: ‘vm.$set()’ has been deprecated so we have to use the global ‘Vue.set()’ method.
Since we no longer use a property to sync the two quantities we can reference the Cart component like this:

<cart></cart>

Notice 2: The ‘lazy ’and ‘number ’ params are now modifiers, so we have to update Cart’s input:

 // Vue 1<input v-model=”quantity” class=”form-control” number>// Vue 2<input v-model.number=”quantity” class=”form-control”>

That’s it! You can view the final code and toy around on JSFiddle.

Useful Resources

Below is a list ofresources that I suggest you to have a look at.

Book Update

For everyone asking if my book will be updated to catch up with Vue 2 changes, the answer is YES! Once Vue 2 is stable, we are planning on updating most book’s examples to demonstrate how to build them with both versions of Vue.

If you haven’t already read it, head to Leanpub to check it out.

Drop me a line

Any feedback or question about this tutorial or anything else would be welcome. You can also follow me on twitter for more updates about Vue.js and Laravel.

--

--