[Vuejs]-Loop out async data in vue component

1πŸ‘

βœ…

The problems you may have met:

  1. menu is null when compile the template, so as @ittus already answered, uses v-if to control the flow.

  2. uses Vue API: $set when adding property into one object. (check Vue: Reactivity in Depth for more details)

So the codes will be like below demo:

Vue.config.productionTip = false
app = new Vue({
  el: "#app",
  data: {
    menu: null,
    loading: false
  },
  mounted: function () {
    this.loading = true
    setTimeout(() => {
      this.menu = this.menu ? this.menu : {}
      this.$set(this.menu, 'items', [{'heading': 'a1'},{'heading': 'b1'}, {'heading': 'c1'}])
      this.loading = false
    }, 1500)
  }
})
<script src="https://unpkg.com/vue@2.5.16/dist/vue.js"></script>
<div id="app">
    <div v-if="!loading">
      <div v-if="menu">
        <ul v-for="item in menu.items">
            <li>{{ item.heading }}</li>
        </ul>
      </div>
      <p v-else>No Data</p>
    </div>
    <p v-else>Loading...</p>
</div>
πŸ‘€Sphinx

1πŸ‘

You can simply check menu is not undefined

<div v-if="menu && menu.items">
    <ul v-for="item in menu.items">
       <li>{{ item.heading }}</li>
    </ul>
 </div>

or in where you get data:

methods: {
  getData() {
    this.loaded = false
    callApi().then(res => {
      this.menu = res // example
      this.loaded = true
    })
  }
}

 <div v-if="loaded">
   <ul v-for="item in menu.items">
     <li>{{ item.heading }}</li>
   </ul>
 </div>
πŸ‘€ittus

Leave a comment