admin管理员组

文章数量:1435859

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>

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>
Share Improve this question asked Oct 18, 2019 at 18:08 codemonkeycodemonkey 5552 gold badges7 silver badges18 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 4

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./bootstrap/dist/css/bootstrap.min.css" />
<link type="text/css" rel="stylesheet" href="https://unpkg./bootstrap-vue@latest/dist/bootstrap-vue.css" />

<script src="https://unpkg./vue"></script>
<script src="https://unpkg./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 ponents.

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./bootstrap/dist/css/bootstrap.min.css" />
<link type="text/css" rel="stylesheet" href="https://unpkg./bootstrap-vue@latest/dist/bootstrap-vue.css" />

<script src="https://unpkg./vue"></script>
<script src="https://unpkg./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: []
    },

    puted: {
      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 puted property will notice that change and re-render your dropdown.

本文标签: javascriptHow to dynamically add vue bootstrap dropwdown list itemStack Overflow