When to use a Vue Render Function
There are very few cases where you should be using a render function instead of regular templates to create components in Vue.js. And the Render Functions API got slimmer in Vue 3. In this article, we’re going to see a few cases where the use of render functions is justified. By the way, if you need an introduction to render functions, make sure you read my previous post on Render Functions.
This article is going to show you some advanced patterns, so strap in and bear with me!
TL;DR: In my opinion, you should only use render functions when you want to intercept the data passed to the component and change it, and only if you cannot do it with regular template functions and props or similar approaches.
So, please, if you can use a template, use it. You and anyone reading the code will thank me later!
Let’s see a few render functions use-cases. And stay until the end to see my favourite one!
# Intercepting HTML attributes
One of the use-cases I’ve found while developing Design Systems based on CSS classes (ahem, Tailwind) is that you want to make certain classes appear alongside other classes in your DS. And if you want to validate that the classes that are passed are consistent with what you expect, you cannot do that with templates, unless you access the DOM or pass classes via props...
Let me show you the principle with a live example:
As you can see, we’re “reading" the classes passed to the component via attrs
, and if the class passed is red
, we make add blue
. When would you want to do such a thing? To enforce consistency or to add your own logic. Imagine you want to have something like this:
- Every time someone passes the
.x
class, you want to make sure.y
class is also present.
So, this pattern is probably only interesting for components library authors or Design System authors, and I recognise it, it’s an edge-case probably you won’t even encounter.
Note: did you notice how we’re creating components inside <script setup>
and defineComponent
? Also, the second component is returning a function. This way, we can use useAttrs
and useSlots
inside of it (instead of this.slots
). And then, by returning a function, it’s treated as a render function.
Unfortunately for us, in Vue 3, the class object is read-only, so you can only add classes and not remove existing ones. But it’s an example of what you can do with render functions. And the same way we have intercepted the class
attribute, you could intercept other HTML attributes.
# Validating slots
for Accessibility
Again, let’s consider you’re creating you’re own Design System. And you want to provide a11y and usability hints when someone does something funky in the template. For example:
- By spec, the
a
element cannot contain any interactive (clickable) elements.
So, what if we try to warn our library users of an incorrect markup, in development, before they even need to check it?
I can see how this kind of message could be useful in a big Design System that focuses on **accessibility** (and why shouldn’t you, right?).
# Rendering dynamic templates
You’ve probably encountered this problem while developing an app. You receive a string from some Backend or API that contains a template or some HTML that needs to interpolate some data. For example, it’s commonly needed for internationalisation (i18n) or rendering dynamic dashboards.
Note: As you might have thought, it is an alternative API to Vue.compile
. And for any compilation during runtime, you would need to load the Vue “build" that includes the compiler, so bear in mind it produces a heavier JS bundle and you’ll need to add it into your configuration manually.
For this example, I will showcase an example I had up my sleeve, using Vue 2:
As you can see, it could be a replacement for v-html
if you need to transpile during runtime some expressions or if you need to compile at runtime components. For example, the <router-view>
is also a very common case. Notice how in my example I'm not implementing methods/events. I just wanted to showcase the main idea.
This pattern is actually the principle behind Alex Jover's v-runtime-template package and many other similar ones. And now you know, it’s not magic at all 😉!
Mandatory note: ❗️ Be careful about rendering user inputs (avoid it or sanitize them), as it can lead to an XSS attack.
# Conclusion
These are some of the use-cases of render functions. I hope you have seen something new or you have learned something! 😊 Let me know other use cases of render functions you know about!
Also, remember, when possible, use templates instead!
Related Articles
Introduction to Render Functions
What is a render function? Let's see a simple example and the comparison with Vue compiled code and its counterpart template compiled code.
Sep 28, 2021
Run watchers when a Vue.js component is created
Tutorial on how to make a watcher run instantly when a Vue.js component is created
Mar 31, 2019
Introduction to Render Functions
What is a render function? Let's see a simple example and the comparison with Vue compiled code and its counterpart template compiled code.
Sep 28, 2021
Sponsors
VueDose is proudly supported by its sponsors. If you enjoy it, consider supporting it to ensure the project maintainability.