[Vuejs]-How to render HTML from a property of items being displayed with v-for loop?

3👍

You could do it using a single wrapper element for the whole lot by concatenating all the HTML in a computed property:

new Vue({
  el: '#app',
  
  data () {
    return {
      outlineItems: [
        { html: '<h1>Heading 1</h1>' },
        { html: '<h2>Heading 2</h2>' },
        { html: '<h3>Heading 3</h3>' }
      ]
    }
  },
  
  computed: {
    outlineHtml () {
      return this.outlineItems.map(item => item.html).join('')
    }
  }
})
<script src="https://unpkg.com/vue@2.6.11/dist/vue.js"></script>

<div id="app">
  <div v-html="outlineHtml"></div>  
</div>

Behind the scenes v-html sets the innerHTML of its corresponding DOM node. A <template> tag doesn’t create a DOM node so the innerHTML can’t be set anywhere.

I would add that v-html is considered an ‘escape hatch’. Where possible you should avoid using it and let Vue create the HTML itself. Generally the approach would be to use a suitable data structure to hold the data (rather than a blob of markup) and then render that data structure within the template.

0👍

One possible solution is to create multiple unique components. You can even pass in props, and there are no wrappers

Vue.component('greeting', {
  template: '<h1>Welcome to coligo!</h1>'
});
Vue.component('titles', {
  template: '<h1>title 1</h1>'
});
Vue.component('title2', {
  template: '<h2>Welcome to coligo!</h2>'
});
Vue.component('title3', {
  template: '<h3>{{text}}</h3>',
  props: ['text']
});

var vm = new Vue({
  el: '#app',
  data: {
  	items: [
    	{ type: 'greeting' },
    	{ type: 'titles' },
    	{ type: 'title2' },
    	{ type: 'title3', text: 'test' }
    ]
  }
});
<script src="https://unpkg.com/vue@2.6.11/dist/vue.js"></script>

<div id="app">
  <component v-for="(item,i) in items" :is="item.type" :text="item.text" :key="i"></component>  
</div>

Leave a comment