在vue组件中循环输出异步数据

时间:2018-06-13 14:58:47

标签: vue.js

我需要加载异步数据然后在vue组件中循环它。我知道循环在我拥有数据之前运行但我无法弄清楚如何重新运行或保持循环直到我有数据。我测试的一个解决方案是无法正常工作的是Data中的一个加载属性和一个isLoaded计算函数,然后是

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

似乎循环仍在运行,我收到了错误 -

TypeError: Cannot read property 'items' of undefined

整个页面似乎在该错误之后冻结,因此可能无法在异步函数中将Data属性设置为true。我已经测试过在创建和挂载的钩子中运行异步。

当我离开页面并返回时,一切正常,可能是因为数据已加载。我还测试了通过按钮单击设置loded属性,它在循环注释时工作正常,而不是在循环运行时。

我认为这是谷歌搜索后的常见解决方案,但我无法让它工作。什么是错的或任何其他建议(我的最后一个是将数据加载到另一页)。

另见 -

export default {
    data() {
        return {
            loaded: false,

和 -

computed: {
    isLoaded() {

        return this.loaded

    }

2 个答案:

答案 0 :(得分:1)

您只需检查menu不是undefined

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

或获取数据的地方:

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>

答案 1 :(得分:1)

您可能遇到的问题:

    编辑模板时
  1. menu is null,以便@ittus已经回答,使用v-if来控制流程。

  2. 在将属性添加到一个对象时,
  3. 使用Vue API: $set。 (查看Vue: Reactivity in Depth了解更多详情)

  4. 所以代码如下所示:

    &#13;
    &#13;
    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)
      }
    })
    &#13;
    <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>
    &#13;
    &#13;
    &#13;