Trung Tran
Trung Tran

Reputation: 13721

How to dynamically render vue.js components?

does anyone know of a way to dynamically render vue.js components? For example, I have a table component that should render different buttons based on the prop definition:

Vue.component('my_table', {
    template: '#my_table',
    props: {
      data: Array,
      columns: Array,
      actions: Array
    }
});

Ideally, my template would be defined in the tmpl value of my action object:

<tbody>
    <tr v-for="entry in data">
      <td v-for="key in columns">
        {{entry[key.field]}}
      </td>
      <td v-for="action in actions">
        {{ action.tmpl }}
      </td>
    </tr>
</tbody>

Here's my fiddle:

https://jsfiddle.net/zfya92dh/43/

Anyone have any ideas?

Thanks in advance!

Upvotes: 1

Views: 3831

Answers (2)

Roy J
Roy J

Reputation: 43881

You just want to insert HTML instead of plain text? Change

<td v-for="action in actions">
    {{ action.tmpl }}
</td>

to

<td v-for="action in actions" v-html="action.tmpl"></td>

However, if your HTML includes Vue markup, the markup will not be respected. You will need to create actual components to represent each of your configurations and then use :is to tell Vue which one to use at a given time. Vue doesn't use string-based templating, so there is no way to make passing a template string work.

Upvotes: 1

Bert
Bert

Reputation: 82459

<component :is="action.tmpl"></component>

Here is your fiddle revised.

const button1 = Vue.extend({
    template:'<button class="btn btn-primary">View</buttton>'
})

const button2 = Vue.extend({
  template:'<button class="btn btn-primary" @click="some_method">Delete</buttton>',
  methods:{
     some_method(){
         alert('clicked')
     }
  }
})

And the relevant data.

 data: {
    actions: [
    {
      name: 'view',
      label: 'View Company',
      method: 'click',
      tmpl: button1
    },
    {
      name: 'delete',
      label: 'Delete Company',
      method: 'click2',
      tmpl: button2
    },
  ],

Upvotes: 1

Related Questions