Как динамически добавить элемент выпадающего списка vue bootstrap? - PullRequest
2 голосов
/ 18 октября 2019

Я пытаюсь динамически добавлять элементы раскрывающегося списка с помощью bootstrap-vue, и у меня возникают проблемы с отображением элементов раскрывающегося списка в браузере. Вот то, что я имею до сих пор, любой вклад будет высоко ценится. Я хочу, чтобы он был динамическим, поэтому, если исходный JSON когда-либо изменится, элементы раскрывающегося списка будут меняться вместе с ним без необходимости возвращаться и изменять код.

ПРИМЕЧАНИЕ: reportData - это список объектов, которыйпочему я устанавливаю первый элемент reportData для newData, из которого я хочу, чтобы элементы раскрывающегося списка отображались.

Компонент раскрывающегося списка:

  <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>

Ответы [ 2 ]

2 голосов
/ 18 октября 2019

Старайтесь избегать прямого манипулирования DOM, когда вы можете использовать Vue. В этом случае лучшим вариантом будет установить текущие активные данные в любой список, который вы хотите отобразить. Затем в шаблоне выполните цикл по каждому из этих активных элементов данных.

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>

Не стесняйтесь, дайте мне знать, если у вас есть какие-либо вопросы.


Редактировать:

Следующий примерможет помочь прояснить, что вам нужно делать, если у вас есть вложенные массивы объектов, структура которых заранее известна.

Однако, если вы не знаете глубину своего дерева, вам, возможно, придется подуматьиспользуя рекурсивные компоненты .

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>
2 голосов
/ 18 октября 2019

попробуйте это

      <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>

В вашем JS ....

    data() {
      items: []
    },

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

Что-то в этом роде. Я не знаю точно, как выглядят ваши данные, но если вы заполните this.list новыми данными, вычисленное свойство заметит это изменение и повторно отобразит ваш раскрывающийся список.

...