Vue Slots Jsx
Vue.js has an easy API and several options for defining HTML templates in our components.
How to set up a Vue project with JSX. For this section, we will be building a trivial app that displays a little bit of information about selected countries. Create a new project. Vue create vue-jsx. Install the dependencies needed to make use of JSX in your project using yarn: yarn add @vue/babel-preset-jsx @vue/babel-helper-vue-jsx-merge-props. Of course, I'm not saying JSX can't do what Vue does. I think with JSX, anything is possible, since it's just Javascript. The point of the article is more towards the ease of using Vue's built-ins to achieve what JSX can do (or better?). JSX has its own beauty, especially the type-checking, that I must say. Render Functions & JSX Basics. Vue recommends using templates to build your HTML in the vast majority of cases. There are situations however, where you really need the full programmatic power of JavaScript.
We can use the <template>
tag option, define a template
property on our root component instance, or use Single-File components.
The options above are awesome and work perfectly, but, there comes a time in the lifecycle of your application where they either feel clunky, over-engineered or very inflexible.
Table of Contents
So, why would we want to JSX instead of any of the other template definitions?
- JSX is easy to read.
<div>...</div>
is subjectively better thanthis.$createElement('div', {}, [...])
- Seriously, It's just JavaScript.
- Vue has support for JSX.
- JSX makes custom Vue components easier to import and manage.
A quick intro
Let me give you an example of why JSX is good.
We want to build a <TextField/>
component that can either be a normal single-line text input or a multiline input (textarea). Our template declaration might look like this.
As you can see from the snippet above, we'll quickly run into a few problems like duplicate code and many more. Imagine having to support a variety of properties on the input. This little snippet above will grow and be a nightmare to maintain.
To fix this, we need to go low-level with Vue. We need to get closer to Vue's internal API to fix this mess.
The render() method
NOTE: I'm not saying that the there's not a simple way or ways to handle the above problem without JSX, all I'm saying is that moving this logic to the render()
method with JSX in tow can make for a more intuitive component. Keep reading to find out why?
Every component we create in Vue has a render method. This is where Vue chooses to render the component. Even if we don't define this method, Vue will do it for us.
This means that when we define HTML templates in Vue — Vue's template compiler compiles it to a createElement
function that takes a couple parameters and returns the result from the render
function.
To fix the code in the previous section, we remove the template
property or the template tag and define a render()
method on the component. If the render
method is defined on a component, Vue will ignore the template definition.
Vue Jsx Slot Props
The above code does a few things:
- The
render
method takes acreateElement
helper from Vue. - We programmatically define our tag.
- Then we create the tag and pass its attributes, classes etc as an object. There are quite a few options we can pass to
createElement
. - We return the newly created element for rendering.
Note:Every template we define for a Vue component will be converted into a render
method that returns a createElement
function. It's because of this reason the render
method will take precedence over a template definition.
Take this example:
The template compiler will convert the HTML above into:
Okay! now you might ask this question, 'Isn't this bad for readability?' The answer is yes. Once you define a component with many levels of elements nesting or has several sibling elements — we run into a new problem. We just sacrificed readability. Like they say, 'we've moved from the frying pan to fire.'
Cue JSX. This is where we'll have JSX bring back the readability we lost.
What is JSX
If you already know about JSX, feel free to skip to the next section where I'll show you how to use JSX in Vue.
JSX is a term coined by Facebook's engineering team.
JSX is an XML-like syntax extension to JavaScript without any defined semantics.
JSX is NOT intended to be implemented by engines or browsers. Instead, we'll use transpilers like Babel to convert JSX to regular JavaScript.
Basically, JSX lets us use an HTML-like syntax in JavaScript.
Unfortunately, this article assumes you already know JSX, so teaching JSX is beyond the scope of this article. I'll still point you in the right direction. JSX is very easy to grok and can be done in a couple minutes.
Use these links to learn The basics of JSX, Learn JSX in-depth, finally, if you really want to know about the specification that is JSX, visit its official website.
Configure Vue to use JSX
If you use Vue-cli greater or equal to version 3.0 you are in luck as JSX is supported.
If you are using an older version of Vue-cli that doesn't support JSX, you can add it by installing babel-preset-vue-app
and add it to your .babelrc
file.
To install:
In you .babelrc
file, all you have to do is:
There, we can now use JSX in our component's render
function.
Vue's JSX syntax gotchas
There are few gotchas to using JSX in Vue.
First, you can no longer use the :
and @
shortcuts for binding and listening to events. They are invalid JSX syntax and your code won't compile.
To listen for events in JSX, we need the 'on' prefix. For example, use onClick
for click events.
To modify events, use:
To bind a variable, instead of :
use:
To set HTML string as the content of an element, instead of v-html
use:
We can also spread a large object.
Using JSX in render
Going back to our initial 'TextField' component. Now that we have JSX enabled in our Vue app, we can now do this.
Importing Vue JSX Components
Another benefit to using JSX in Vue is that we no longer have to register every component we need. We just import and use.
How to make JSX work with TypeScript
TypeScript is used as a mechanism that adds type-checking to JavaScript. You can read more.
To add JSX support to TypeScript all we need to do is modify our tsconfig.json
.
To enable JSX in TypeScript, first save the file as a .tsx
file and modify your tsconfig.json
to include:
Setting the jsx
option to 'preserve' means that TypeScript should not process the JSX. Doing this lets Babel take control of everything JSX and TypeScript stick to types as it does not yet support Vue JSX. You can learn more.
Then create a jsx.d.ts
file in your project and add the TypeScript JSX declarations for Vue.
Vue Jsx Slot Name
Make sure that TypeScript can load the declaration file. Or, you can add autoloading for it in tsconfig.json
via:
Conclusion
Vue Scoped Slots Jsx
That's it for today. Enjoy having some or all of your Vue.js templates in JSX.
And, please no complaints about JSX breaking SOC (separation of concerns), I can't take another one of those arguments. If you prefer using the createElement
function with objects by all means enjoy!!
Let me know your thoughts and suggestions in the comments.
Cheers!
Like this article?Follow @KayandraJT on Twitter