【问题标题】:Vue.js - call API and render response from child single-file componentVue.js - 调用 API 并从子单文件组件呈现响应
【发布时间】:2018-02-03 20:18:49
【问题描述】:

Vue.js 版本 2,带有单文件组件和 vue-router(和 webpack,但在这里不应该很重要)。

我已经对此进行了研究,并且我相信我可以并且似乎无法解开一个在渲染组件时填充和渲染对象的良好模式,希望解决方案对某人来说是显而易见的,并且很容易解释。

Main.js(从 webpack.base.config 调用):

var vm = new Vue({
  el: '#app',
  router,
  template: '<App/>',
  components: { App }
})

App.vue:

<template>
    <router-view></router-view>
</template>

<script>
    export default {
      name: 'app'
    }
</script>

Child.vue(重要的是要注意我在这里所做的是 1)进行 api 调用(通过 javascript 承诺)2)迭代响应并填充 temp Object @ 987654325@ 具有每个重要位的键和值的属性,然后 3) 触发computed.cObj.set() 以呈现列表):

<template>
  <div class="child">
    <ul>
      <li v-for="i in cObj">{{ i }}</li>
    </ul>
  </div>
</template>

<script>
    export default {
      name: 'child',
      data () {
        return {
          obj: {}
        }
      },
      computed: {
        cObj: {
          get: function () {
            return this.obj
          },
          set: function (nv) {
            this.obj= nv
          }
        },
        // cObj: function () {
          // return this.getAll()
        // }
      },
      created () {
        let conditional = true
        if (!conditional) // ...do something else
        else this.getAllX()
      },
      methods: {
        getAll: function () {
          let x = {} // temporary object

          // in this promise I'm returning data from the server
          server.getData()
            .then(function (r) {

              // iterate response
              r.records[0].operations().then(r => {
                for (let a in r) {
                  if (typeof r[a].records === 'object') {
                    for (let b in r[a].records) {
                      Object.keys(r[a].records[b]).forEach(function (key) {
                        if (r[a].records[b][key] !== undefined) {
                          // add key/value to x
                          x[key] = r[a].records[b][key]
                        }
                      })
                    }
                  }
                }
              })
            })
            .catch(function (err) {
              console.log(err)
            })
          this.cObj = x // THIS IS WHAT IS KILLING ME HERE, I must be misunderstanding the documentation here because the computed `set` method isn't triggered or I'm misunderstanding vue lifecycle, I thought calling the computed.cObj.set() should trigger the rendering of the list but it does not. 
          // return x | tried this as well (see commented out computed.cObj)
        }
      }
    }
</script>

查看控制台中填充的对象,我得到以下信息,但未呈现列表:

// {}
// detailOne: "asdf"
// detailTwo: "asdf asdf"
// __proto__: Object { … }

这是一个类似的问题Vue.js : How to make dynamic menu?

【问题讨论】:

  • 为什么需要一个计算属性?您可以将 cObj 初始化为数据,然后像 this.cObj = x; 那样简单地设置它
  • 谢谢,我会试一试。如果我错了,请纠正我,如果我理解正确你说我应该设置this.data = x。编辑:我相信你的意思是把计算出的cObj 移到数据中,试试看。
  • 不。我会给你一个更完整的样本。等一下:)
  • 是的,将 cObj 移至数据 :)
  • 好的,谢谢...测试。编辑:无赖!也没有用。与之前一样,填充了 cObj(每个控制台输出),但在填充对象后组件不会呈现数据:/.

标签: javascript ajax vuejs2


【解决方案1】:

在你的 Child.vue 中试试这个:

数组方式:

<template>
  <div>
    <ul>
      <li v-for="(item, index) in cObj" :key="index">{{ item.name }}</li>
    </ul>
  </div>
</template>

<script>
export default {
  data () {
    return {
      cObj: {}
    }
  },
  created () {
      let conditional = true
      if (!conditional) {

      }
      else {
        this.getAll()
      }
    },
    methods: {
      getAll: function () {
        let x = [
          { id: 1, name: 'one' },
          { id: 2, name: 'two' },
          { id: 3, name: 'thre' },
        ]
        this.cObj = x;
      }
    }
}
</script>

对象方式:

<template>
  <div>
    <ul>
      <li v-for="(value, key) in cObj" :key="key">{{ key }} : {{ value.name }}</li>
    </ul>
  </div>
</template>

<script>
export default {
  data () {
    return {
      cObj: {}
    }
  },
  created () {
      let conditional = true
      if (!conditional) {

      }
      else {
        this.getAll()
      }
    },
    methods: {
      getAll: function () {
        let x = {
          first: { id: 1, name: 'one' },
          second: { id: 2, name: 'two' },
          third: { id: 3, name: 'three' },
        };
        this.cObj = x;
      }
    }
}
</script> 

【讨论】:

  • 根据您的编辑,该对象与我得到的不同(请参阅原始帖子末尾附近已注释掉的对象)。对象可能是这里的问题吗?旁注,我认为这个问题是我对生命周期缺乏了解,因为我已经看到列表填充,但是当它填充时它是一种黑客,因为它仅在我保存对代码的更改和热门时才会呈现触发了重新加载(但当然我无法让列表自然呈现)。我会尝试像你一样将它渲染为一个(对象)数组。
  • 对不起。它也应该适用于数组和对象。数组:vuejs.org/v2/guide/…,对象:vuejs.org/v2/guide/list.html#v-for-with-an-Object
  • 我更新了代码以证明这两种方式都有效。希望你也一样。
  • 再次感谢您,并且...同意...但是我发现我正在构建的对象可能有问题,并且在您的示例中缺少我的问题的“关键部分”正在循环响应并构建临时对象并将临时对象设置为 vue 数据项。我很确定你列出的答案将帮助所有面临同样问题的人,但我需要它在本地工作,然后才能关闭它,所以我试图找到我在本地失败的地方并将尽快选择答案。
  • 谢谢,在干预之后,将 x 设置为一个数组并使用 x.push(... 为我带来了最终的不同。我选择这个作为答案的主要原因是 computed: 属性不是必需的。
猜你喜欢
  • 2020-03-20
  • 2022-11-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-11
  • 2015-04-17
  • 2022-12-04
  • 2016-12-13
  • 2021-11-25
相关资源
最近更新 更多