[Vuejs]-How to apply dynamically created template for Vue.js instance?

0👍

Check Dom template,

The HTML Content Template () element is a mechanism for
holding client-side content that is not to be rendered when a page is
loaded but may subsequently be instantiated during runtime using
JavaScript.

<template> contains one content attribute, normally we will read template content by this attribute. so you may add your html into the content.

If directly appendChild to <template>, you can print out the html, then will find nothing already been added.

Simply fix: just change dynamicTemplate.appendChild(childDiv) to dynamicTemplate.content.appendChild(childDiv)

because some browsers may not support <template>, you may have to use <div> instead then hide it.

PS: I found some documents said the attribute=content of <template> is readonly HTMLTemplateElement, probably use div instead template will be better.

Also you could try vue render(), it will be better for your case.

function isSupportTemplate() {
  return 'content' in document.createElement('template')
}

function createVueInstance(supported) {
  if(supported) {//check browser whether support template
    var dynamicTemplate = document.createElement('template');
    dynamicTemplate.id = 'dynamicTemplate';
    var childDiv = document.createElement('div');
    childDiv.innerText = 'support <template>: {{text}}-{{text}}';
    dynamicTemplate.content.appendChild(childDiv); //apend your html to template content
    document.body.appendChild(dynamicTemplate)

    var staticTemplate = document.getElementById('staticTemplate');
    document.body.insertBefore(dynamicTemplate, staticTemplate);
  }
  else {
    var dynamicTemplate = document.createElement('div');
    dynamicTemplate.id = 'dynamicTemplate';
    dynamicTemplate.style.display = 'none'
    var childDiv = document.createElement('div');
    childDiv.innerText = 'not support <template>: {{text}}-{{text}}';
    dynamicTemplate.appendChild(childDiv); //append your html to template content
    document.body.appendChild(dynamicTemplate)

    var staticTemplate = document.getElementById('staticTemplate');
    document.body.insertBefore(dynamicTemplate, staticTemplate);
  }

  new Vue({
    el: '#firstPlaceholder',
    template: '#staticTemplate',
    data: {
      text: 'My first text'
    }
  }); 

  new Vue({
    el: '#secondPlaceholder',
    template: '#dynamicTemplate',
    data: {
      text: 'My second text'
    }
  });
}
<!doctype html>
<html>

<head>
       <script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>

<body>
  <button onclick="createVueInstance(isSupportTemplate())">Support Template</button>
  <button onclick="createVueInstance(!isSupportTemplate())">Not Support Template</button>
    <template id = "staticTemplate">
      <div>{{text}}</div>
    </template> 
  
    <div id ="firstPlaceholder"></div>
  
    <div id ="secondPlaceholder"></div>      
    
</body>
</html>

0👍

It is not directly usable in your example as is, but maybe you could obtain the desired result using Async Components.

Leave a comment