Asynchronously loading Vue component template

Problem:

When developing a Vue application that interfaces with a CMS (WordPress in my case), you’ll run into the issue of displaying rendered html sent from the server in your components.  The normal way of rendering content in a component is to render strings into the template.

{{ yourVariable }}

String interpolation is great, but that doesn’t work if you want to render HTML or Vue components. Vue allows developers to define a component asynchronously with a promise, but the promise scope has no access to data or props.  Asynchronously defined components can’t get a string that is already in a parent component.

Solution

Define a child component in the parent component’s data, and use :is="" in the template.  This allows you to dynamically define the child component, and render it when the string is ready.  Templates need to be defined at component creation, but this allows you to delay creation and generate the component when the data is ready.

Here is an example of defining a component in the data object.

See the Pen Child component from data variable Example by John H Horton (@Johnhhorton) on CodePen.0

This example shows that a defined global component tag will be rendered from the template string.

See the Pen Global component from data variable Example by John H Horton (@Johnhhorton) on CodePen.0

This is an example of asynchronously defining the component.  Click ‘Result’ and wait 3 seconds.

See the Pen Global component from async data variable Example by John H Horton (@Johnhhorton) on CodePen.0

If you apply this method, you aren’t limited by what you do with content strings.  You can save components tags in your content, and render them when the content is loaded asynchronously

In a content heavy site you will have to use a content component a lot. Create a global content-component that handles this everywhere.

In my example, the content-component is creating a new component to render the content. The content-area component receives a content string via props. The child component is dynamically created using the content prop as its’ template.

See the Pen Content Component by John H Horton (@Johnhhorton) on CodePen.0

There are other ways to organize a content-component.  If you come up with a better version, let me know!

Edit:

Rheinard Korf provided a far more concise method using a computed property. Example below:

See the Pen Content Component by Rheinard Korf (@rheinardkorf) on CodePen.0


Also published on Medium.

2 Replies to “Asynchronously loading Vue component template”

    1. Hi Rheinard,

      That solution is more more concise! My only concern would be: what happens when a data variable that the computed property is dependent on changes? Granted, that’s still an issue with my approach. If we want to have a child component that control’s its’ own data, we’ll need to be careful not to cause a rerender by changing the content property.

      I’m going to implement your approach in my own projects =)

Leave a Reply

Your email address will not be published. Required fields are marked *