0
votes

I am using Bootstrap Vue to build a reusable Drowndown component. I would like to dynamically render different elements: item, title, and divider. How can I do this?

So what I want to achieve is the Dropdown component like this:

<template>
    <b-dropdown>
      <b-dropdown-{{option.element}} 
        v-bind:key="index"
        v-for="option in data"
        :value="option.id"
        >{{ option.value }}</b-dropdown-{{option.element}}
      >
    </b-dropdown>
</template>

<script>
export default {
  name: 'Dropdown',
  props: {
    data: data
  }
}
</script>

So that it would render like

    <b-dropdown-title>I am a title</b-dropdown-title>
    <b-dropdown-item>And I am an item</b-dropdown-item>
    <b-dropdown-item>I am another item</b-dropdown-item>
    <b-dropdown-divider></b-dropdown-divider>

Then from the parent component, I could pass data like:

<Dropdown id="modules-dropdown" v-data="data"></Dropdown>

import Dropdown from './Dropdown'
const dropdownData = [{id: 1, value: 'I am a title', element: 'title'}, {id: 2, value: 'And I am an item', element: 'item'}, {id: 3, value: 'I am another item', element: 'item'}, {id: 4, element: 'divider'}] 
export default {
  name: 'ParentComponent',
  components: {
    Dropdown
  },
  data () {
    return {
      data: dropdownData,
    }
  },
}
1

1 Answers

1
votes

What you want is a Dynamic Component, which allows you to define which component should be rendered using the is prop.

new Vue({
  el: '#app',
  data() {
    return {
      options: [
        { value: "Hello", element: 'header' },
        { value: "Item 1", element: 'item' },
        { value: "Item 2", element: 'item' },
        { value: null, element: 'divider' },
        { value: "Item 3", element: 'item' },
        { value: "Item 4", element: 'item' }
      ]
    }
  }
})
<script src="https://unpkg.com/[email protected]/dist/vue.min.js"></script>
<script src="https://unpkg.com/[email protected]/dist/bootstrap-vue.js"></script>

<link href="https://unpkg.com/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://unpkg.com/[email protected]/dist/bootstrap-vue.css" rel="stylesheet" />


<div id="app">
  <b-dropdown text="Dropdown">
    <component 
      :is="`b-dropdown-${option.element}`" 
      v-for="(option, index) in options"
      :key="index" 
    >
      {{ option.value }}
    </component>
  </b-dropdown>
</div>