An easy task to solve with a meta component in Vue
Tags: vue, webdev, opensource, showdev
Published: 2019-11-19 16:42:47

Sometimes you can’t know which of the components you’ll end up having to render on the page and when. Our Ptah editor is a good example - it is the user who decides what components are placed, where they are placed and when to place them.

There may be various solutions, but we’ll talk about the one we ended up using in Ptah. We’ll discuss the sample code and then see what we ended up with in production.

### Problem

Let’s imagine we have a `FirstScreen` section that displays `Text`, `Logo` and `Button` elements. Then at some point, we’ll want to also display the `SocialIcons` element.

```
/ sections
 -- FirstScreen.vue
/ elements
 -- Text.vue
 -- Logo.vue
 -- Button.vue
 -- SocialIcons.vue
```

We can’t control when the user decides to enable the `SocialIcons` element on the web app. Meaning we could render all 4 elements and wrap the code in conditionals to trigger the visibility. This would scale poorly though, and there’s a much better solution.

### Solution sample

The `<component>` has `:is attribute` that can take a component name as a parameter and solve our task with a code like this:

```javascript
<script>
export default  {
  name: 'FirstScreen',

  data () {
    return {
      elements: [
        'Text',
        'Logo',
        'Button',
      ],
    }
  }
}
</script>

<template>
  <div class="first-screen">
    <component v-for="element in elements" :is="element"/>
  </div>
</template>

```

The `elements` array contains the components’ names that are displayed in a `v-for` cycle under `FirstScreen` template. So to display a new element we just have to push it to the array - `this.elements.push(‘SocialIcons’)`.

### Solution in production

The product quality implementation ended up being more complex, yet the idea stays the same - we run through the `$sectionData.components` array and display the contents. You can [see the code of the template](https://github.com/ProtocolONE/ptah-editor/blob/f33f81ed7b299c53dad5e569b22231f38ac788c6/src/components/sections/first-screen/FirstScreenFantasy01.vue#L259) that starts from line 259. It has a lot of dependencies and parameters what is fair for a project of this size. The logic for managing the elements is elsewhere. 

Again, we can’t predict which component code gonna end up on the rendered web page and when, since Ptah is a WYSIWYG editor for building landing websites. Naturally, all elements (such as [a button, a form, a logo, a text](https://github.com/ProtocolONE/ptah-editor/tree/develop/src/components/elements)) can be rearranged, added and removed accordingly to however user feels like.

[Here is a demo](https://ptah.super.com/), if you’re curious. Click “try the demo” button to play with the editor. Or here’s a gif to save you a click:

![sdf](https://github.com/ProtocolONE/ptah-editor/blob/develop/docs/ptah-editor.gif?raw=true)

### Conclusion

Dynamic and meta components are essential for Vue and can help solve many problems. Here’s one small take and a `problem-->draft solution-->production solution` story.

If you found it useful to scroll through this short read, let me know so another one happens. About mixins.

{% github https://github.com/ProtocolONE/ptah-editor %}