0

I am able to use a static template with a Vue.js instance as shown below. The content of the firstPlaceholder is replaced with the content of the template staticTemplate and the text property is rendered correctly. (Might require Chrome to work correctly.)

However, if I create a template dynamically, the rendering does not work. The secondPlaceholder is missing. Maybe this is a timing issue?

=>How can I adapt my code to render the secondPlaceholder using the dynamicTemplate?

<!doctype html>
<html>

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

<body>
  
    <template id = "staticTemplate">
      <div>{{text}}</div>
    </template> 
  
    <div id ="firstPlaceholder"></div>
  
    <div id ="secondPlaceholder"></div>      
	
	<script>
    
    	var dynamicTemplate = document.createElement('template');
      dynamicTemplate.id = 'dynamicTemplate';
      var div = document.createElement('div');
      div.innerText = '{{text}}';
      dynamicTemplate.appendChild(div);
      
      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'
        }
      });       
     
	</script>
</body>
</html>

Related question:

How to target custom element (native web component) in vue.js?

2 Answers 2

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>

Sign up to request clarification or add additional context in comments.

Comments

0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.