简体   繁体   中英

How to dynamically add vue bootstrap dropwdown list item?

I'm trying to dynamically add drowdown list items using bootstrap-vue, and I'm having trouble getting the dropdown list items to render to the browser. Here's what I have so far, any input would be much appreciated. I want it to be dynamics so that if the original JSON ever changes the dropwdown list items will change with it without having to go back and change the code.

NOTE: the reportData is a list of objects, which is why I'm setting the first element of the reportData to the newData that i want the dropdown list items to be rendered from.

Dropdown List Component:

  <section class="drop-down">
    <div>
      <b-dropdown id="dropdown-list" text="Error Reports" class="m-md-2">
       <b-dropdown-item >ITEM</b-dropdown-item>
        <b-dropdown-divider></b-dropdown-divider>
      </b-dropdown>
    </div>

    <button @click="changeReport">Click to change</button>
  </section>
</template>

<script lang="js">

  export default  {
    name: 'drop-down',
    props:['reportData'],
    data () {
      return {
        newData: this.reportData[0]
      }
    },
    methods: {
      changeReport(){
        this.newData = this.reporData[1]
      }
    },
    watch: {
      newData : function(val, OldVal){
        var dropdownList = document.getElementById("dropdown-list")
          for (var key in val){
            console.log(key)
            var dropdownItem = document.createElement('b-dropdown-item')
            dropdownItem.value = key
            dropdownList.add(drowdownItem, 0)
          }
      }
    }
}


</script>

<style>

</style>

Try to avoid directly manipulating the DOM when you can while using Vue. In this case, your best option would be to set the currently active data to whatever list you want to display. Then, in the template, loop though each of those active data items.

 new Vue({ el: "#app", data: { reportData: [{ text: 'Item 1 Text', value: 'Item 1 Value' }, { text: 'Item 2 Text', value: 'Item 2 Value' }, { text: 'Item 3 Text', value: 'Item 3 Value' }], } })
 <link type="text/css" rel="stylesheet" href="https://unpkg.com/bootstrap/dist/css/bootstrap.min.css" /> <link type="text/css" rel="stylesheet" href="https://unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.css" /> <script src="https://unpkg.com/vue"></script> <script src="https://unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.js"></script> <div id="app"> <section class="drop-down"> <b-dropdown text="Error Reports" class="m-md-2"> <b-dropdown-item v-for="(item, key) in reportData":key="key"> {{ item.text }}: {{ item.value }} </b-dropdown-item> </b-dropdown> </section> </div>

Feel free to let me know if you have any questions.


Edit:

The following example may help clarify what you need to do if you have nested arrays of objects that you know the structure of ahead of time.

However, if you don't know the depth of your tree, you may have to consider using recursive components .

 new Vue({ el: "#app", data: { // This is your input data dataStore: [{ name: 'Item 1', value: [{ text: 'SubItem 1 Text', value: 'SubItem 1 Value' }, { text: 'SubItem 2 Text', value: 'SubItem 2 Value' }, { text: 'SubItem 3 Text', value: 'SubItem 3 Value' }] }, { name: 'Item 2', value: [{ text: 'SubItem 1 Text', value: 'SubItem 1 Value' }, { text: 'SubItem 2 Text', value: 'SubItem 2 Value' }, { text: 'SubItem 3 Text', value: 'SubItem 3 Value' }, { text: 'SubItem 4 Text', value: 'SubItem 4 Value' }, { text: 'SubItem 5 Text', value: 'SubItem 5 Value' }, ] }], // This is the data we will display activeData: null }, created() { // The value that will be selected upon creation this.activeData = this.dataStore[0] }, methods: { changeData() { this.activeData = this.dataStore[1] } } })
 <link type="text/css" rel="stylesheet" href="https://unpkg.com/bootstrap/dist/css/bootstrap.min.css" /> <link type="text/css" rel="stylesheet" href="https://unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.css" /> <script src="https://unpkg.com/vue"></script> <script src="https://unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.js"></script> <div id="app"> <section v-if="activeData" class="drop-down"> <h2>{{ activeData.name }}</h2> <b-dropdown text="Error Reports" class="m-md-2"> <b-dropdown-item v-for="(item, key) in activeData.value":key="key"> {{ item.text }}: {{ item.value }} </b-dropdown-item> </b-dropdown> </section> <button @click="changeData">Change Data Item</button> </div>

try this

      <b-dropdown id="dropdown-list" text="Error Reports" class="m-md-2">
       <b-dropdown-item v-for="item in listItems">@{{ item }}</b-dropdown-item>
        <b-dropdown-divider></b-dropdown-divider>
      </b-dropdown>

      <button @changeReport>Click To Change</button>

In your JS....

    data() {
      items: []
    },

    computed: {
      listItems() {
        return this.items;
      }
    },
    methods: {
      changeReport(){
        this.items = this.reporData[1]
      }

Something like that. I don't know exactly what your data looks like, but if you fill this.list with your new data, the computed property will notice that change and re-render your dropdown.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM