What’s New in Vue.js 2.0 - Beyond Templates With JSX

Anthony Gore
Vue.js Developers
Published in
4 min readOct 17, 2016

A major new feature in Vue.js 2.0 is the virtual DOM. We discuss some of the cool things that can do in a previous article.

One of those cool things is that you can create reactive elements in Javascript code rather than in your HTML template. The virtual DOM will rendered them into the “real” DOM:

data: {
msg: 'Hello world'
},
render (h) {
return h(
'div',
{ attrs: { id: 'my-id' },
[ this.msg ]
);
}

Renders as:

<div id='my-id'>Hello world</div>

This opens up interesting possibilities. For example, you can use the Javascript extension JSX, made famous by React.

In this article we’ll take a look at how to use JSX in a Vue project.

Note: this article was originally posted here on the Vue.js Developers blog on 2016/10/17

JSX in brief

JSX is an extension for Javascript that allows you to put XML-like tokens into your Javascript code. It’s most easily explained with an example:

data: {
msg: 'Hello world'
},
render (h) {
return (
<div id='my-id'>,
{ this.msg }
</div>

);
}

But JSX is not meant to be interpreted by the browser. It must be first transpiled into standard Javascript, similar to how SASS first needs to be transpiled to CSS.

Vue with JSX

The Vue framework doesn’t specifically support JSX….it doesn’t need to since JSX is transpiled into standard Javascript.

So then how do they work together? Because Vue has a virtual DOM implementation, you can use JSX or any pre-processed language so long as it transpiles to something valid for the render function.

A new plugin called babel-plugin-transform-vue-jsx has been introduced to the Vue ecosystem to do exactly that. We’ll look at how to use it in a moment.

Why use JSX with Vue?

But firstly, why use JSX? It’s not required, or even recommend, it’s just a matter of taste. Some people find it much easier to use JSX syntax than to use the render function with pure JS. Others find it dirty to mix HTML in with their JS.

Here’s an example, and you can decide if you like it or not.

Firstly, let’s use good ol’ fashion Vue syntax to create a dead-simple Vue app:

script.js

new Vue({
el: '#app',
data: {
msg: 'Click to see the message'
},
methods: {
hello () {
alert('This is the message')
}
}
});

index.html

<div id="app">
<span
class="my-class"
style="cursor: pointer"
v-on:click="hello"
>
{{ msg }}
</span>
</div>

All it does is displays a span with the text content “Click to see the message”. When you click the span it will trigger an alert. Crazy stuff, right?!

Using a Vue 2 render function instead

In Vue.js 2.0 we can now use a render function to create our reactive element. The following code does exactly the same thing as the above code, the only difference here is that rather than creating a “real” span element, we create a virtual span element which Vue will then render via it’s virtual DOM:

script.js

new Vue({
el: '#app',
data: {
msg: 'Click to see the message'
},
methods: {
hello () {
alert('This is the message')
}
},
render (createElement) {
return createElement(
'span',
{
class: { 'my-class': true },
style: { cursor: 'pointer' },
on: {
click: this.hello
}
},
[ this.msg ]
);
},

});

index.html

<div id="app"><!--span will render here--></div>

Using JSX instead

In our third iteration, again our app will do exactly the same thing. This time, though, we will use JSX in our render function:

script.js

new Vue({
el: '#app',
data: {
msg: 'Click to see the message.'
},
methods: {
hello () {
alert('This is the message.')
}
},
render: function render(h) {
return (
<span
class={{ 'my-class-3': true }}
style={{ cursor: 'pointer' }}
on-click={ this.hello }
>
{ this.msg }
</span>
)
}

});

(index.html same as above)

babel-plugin-transform-vue-jsx

As previously explained, the JSX in that third example will need to be transpiled, so there’s an additional build step which we’ll demonstrate briefly. We’re going to use Babel and Webpack to do the transpiling.

In your webpack.config.js, use the babel loader like normal:

loaders: [
{ test: /\.js$/, loader: 'babel', exclude: /node_modules/ }
]

But in your .babelrc you’ll need to use babel-plugin-transform-vue-jsx as a plugin:

{
"presets": ["es2015"],
"plugins": ["transform-vue-jsx"]
}

Now, when you do a webpack build, your JSX will be transpiled into standard JS.

We demonstrate this in more detail in this video:

--

--