DEV Community

Cover image for Master Vue's render function by creating a custom grid component
Chris
Chris

Posted on

Master Vue's render function by creating a custom grid component

For those of you writing Frontend applications with ReactJs, you are probably familiar with render functions to control what is rendered once the component is ready.

In Vue you usually go for its template solution to control what is being rendered. It is really powerful and offers lots of custom directives, which are prefixed by a v-. You can for example conditionally render a DOM node depending on your current state.

While this already offers a great amount of flexibility, you may sometimes reach for Vue's render function to fully control the html being rendered. Imagine having to apply custom class attributes to children being passed to your custom component.

This is exactly what we will be going for in this tutorial.

I will be utilizing Tailwind CSS, as it offers everything we will need for a basic flexbox grid. I found the class names it is using very intuitive and its utility-first approach goes very well with Vue components.

The render function

Using render gives you control over a function that is called createElement, or h for short.

Hint: In this tutorial I will be naming the createElement function h.

A very simple example of a render function can look like the following:

The example above will render an h1 element with the content of "This is a heading". Pretty straightforward.

createElement syntax

So let's have a look of how createElement works and what can be supplied.

As you can see, the function accepts 3 arguments:

  • The HTML tag name that should be rendered
  • The data object, which defines how to configure this element. You can find more information about it here.
  • The children

With this information, let's create a basic grid component.

This component doesn't do much yet. It simply renders a div element with a class of "flex" and no children.

I would like the grid to render anything what I pass in. Vue uses the concept of slots for this. To read the default prop in Vue, you can use this.$slots.default

Great, this will render the children the pass into the grid component.

So how do we make the grid more flexible? We would like to the tell the grid of many columns it consists of. This way we know which class names to apply. So it sounds like we need a prop in our grid component:

I am using prop validation here, to make sure we are not using any arbitrary class name that the default tailwind configuration doesn't support. By default it uses w-1/2 through w-1/6.

Apply the class names to children

As we don't want to modify the children directly, we will add an additional wrapper around each child and apply the tailwind class names to them. This way we don't have to mess with the child elements directly, which might potentially mess them up:

This reads as follows:

  • Create a div element with class "flex"
  • Map over the default slot and for each child create a new div with a class depending on the cols prop and put the actual child inside of that.

Example usage

So how do you actually use this component in your application?

To make clear what is rendered, this is the final HTML:

Please note that passing in :cols="3", but only 2 children will mess up the layout. You could easily account for that by checking before you render. Depending on your requirements, you could not render nothing or just spit out a console.error/warning.

Troubleshooting

I noticed this.$slot.default consisting of 3 children instead of the expected 2. This was because there has been a space character somewhere between the components. To account for this I added an additional filter before iterating the children:

Top comments (0)