-
Notifications
You must be signed in to change notification settings - Fork 7
Using JSX with Vue.js
Love it or hate it, JSX is a popular extension to Javascript that allows XML tokens in your scripts.
If you want to create templates in your script files and you find Vue's render()
function to be difficult to work with, JSX may be just what you need.
To demonstrate, here's a render function without JSX:
render (h) {
return h(
'div',
{ attrs: { id: 'my-id' },
[ this.msg ]
);
}
And with JSX:
render (h) {
return (
<div id='my-id'>,
{ this.msg }
</div>
);
}
If nothing else, it's much easier to read!
Of course, JSX cannot be interpreted by the browser. It must be first transpiled into standard Javascript, similar to how SASS first needs to be transpiled to CSS. More on this later.
Note: this article was originally posted here on the Vue.js Developers blog on 2017/02/27
There are many ways to specify a template in Vue:
- Using an HTML file
- Using a
template
property in your instance/component constructor - Using
<template>
tags in single file components - Using a render function.
If you go with option 4, you have to create your nodes in a very unfamiliar way i.e. using the createElement
Javascript syntax.
JSX allows you use a render function and still have the look and feel of HTML. Some people find this much easier. Others find it dirty to mix HTML in with their JS.
Have a look at this example and you can decide if you like it or not.
We're now going to create a dead-simple app that displays a span with the text content “Show the message”. When you click the span it will trigger an alert.
Firstly, let’s use Vue in the normal way with separate JS and HTML files:
script.js
new Vue({
el: '#app',
data: {
msg: 'Show the message'
},
methods: {
hello () {
alert('Here is the message')
}
}
});
index.html
<div id="app">
<span class="my-class" v-on:click="hello">
{{ msg }}
</span>
</div>
The following code does exactly the same thing as the above code, the only difference is that rather than using a template we will use a render function to create our template:
script.js
new Vue({
el: '#app',
data: {
msg: 'Show the message'
},
methods: {
hello () {
alert('Here is the message')
}
},
render (createElement) {
return createElement(
'span',
{
class: { 'my-class': true },
on: {
click: this.hello
}
},
[ this.msg ]
);
},
});
index.html
<div id="app">
<!--span will render here-->
</div>
The render function is a little hard to read, right? And that's just for one span, imagine using it for a more complex component!
Let's use JSX now:
script.js
new Vue({
el: '#app',
data: {
msg: 'Show the message.'
},
methods: {
hello () {
alert('This is the message.')
}
},
render(h) {
return (
<span class={{ 'my-class': true }} on-click={ this.hello } >
{ this.msg }
</span>
)
}
});
(index.html same as above)
JSX is just for development and will be transpiled away long before runtime. So we only need to consider JSX in terms of how it benefits our development flow (or not).
To transpile your JSX you can use the babel-plugin-transform-vue-jsx
module which is a plugin for Babel and Webpack. Simply add it to your Webpack config:
{
test: /\.js$/,
exclude: [/node_modules/],
use: [{
loader: 'babel-loader',
options: { presets: ['es2015'], plugins: ['transform-vue-jsx'] }
}]
}
Now, when you do a webpack build, your JSX will be transpiled into standard JS.
Get the latest Vue.js articles, tutorials and cool projects in your inbox with the Vue.js Developers Newsletter