如何动态添加Vue Bootstrap下拉列表项?

3
我正在尝试使用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个回答

4

当您使用Vue时,尽可能避免直接操作DOM。在这种情况下,最好的选择是将当前活动数据设置为要显示的任何列表。然后,在模板中,循环遍历每个活动数据项。

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>


是的,我认为这样做可能是最好的。如果我的数据中有一个值的数组对象,你有什么建议?例如: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: [{ text: 'Item 1 Text', value: 'Item 1 Value' }, { text: 'Item 2 Text', value: 'Item 2 Value' }, }], } }) - codemonkey
我添加了一个编辑,解释了如何处理嵌套的对象数组。然而,如果您事先不知道树的结构或深度,最有可能需要使用递归组件。 - Chase Ingebritson

2

试试这个

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

类似这样的。我不知道你的数据具体是什么样子,但如果你用你的新数据填充this.list,计算属性会注意到这个变化并重新渲染下拉菜单。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接