VueJS异步组件数据和承诺

Swa*_*der 11 javascript asynchronous promise vue.js vue-component

尝试使用VueJS 2.0 RC,并使用fetch API为某些组件加载一些数据.这是一个模拟的例子:

const Component = {
  template: '#comp',
  name: "some-component",
  data: function () {
    return {
      basic: data.subset,
      records: function () {
        return fetch('/datasource/api', {
          method: 'get'
        }).then(function (response) {
          return response.json();
        }).then(function (response) {
          if (response.status == "success") {
            return response.payload;
          } else {
            console.error(response.message);
          }
        }).catch(function (err) {
          console.error(err);
        });
      }
    }
  }
};
Run Code Online (Sandbox Code Playgroud)

data对象是一个全局应用程序状态,在应用程序初始化之前定义,并且组件中只需要它的一部分,因此该部分.组件数据的主要集合来自我试图调用的另一个端点.但是,该data属性需要一个对象,并且它返回一个Promise,它不能真正用于模板中的循环上下文以进行渲染等(例如v-for="record in records")

我是以错误的方式来做这件事的吗?records完全获取后,数据属性更新的方法是什么?有没有办法强制代码停止,直到promise解决(有效地使其同步)?无论如何,该组件没有数据是没用的,所以在它可以被使用之前有一段等待时间.

不使用vue-async或vue-resource等插件的情况下异步填充组件数据字段的正确方法是什么?

(我知道我可以使用非承诺ajax调用的XHR/jQuery方法来做到这一点,但我想学习如何使用fetch做到这一点)


更新:我尝试定义一个创建的钩子,以及一个加载数据的方法,比如这个但没有骰子 - 在我自己的实验中,一旦加载了records属性就无法更新.即使数据已成功获取(成功登录到控制台),它也不会更改.

可能与我使用vue-router和我正在处理单击链接时触发的组件有关,而不是常规的Vue组件.进一步调查......


更新2:如果我继续调查上述的jsfiddle方法和日志this.recordsresponse.payload控制台,它显示对象被填充的记录.但是,这似乎不会触发模板或组件本身的更改 - 使用Vue dev工具进行检查时,records属性仍为空数组.实际上,如果我在logstuff调用它的模板中添加一个方法和一个按钮,然后让这个方法登录this.records到控制台,它会记录一个带有空数组的观察者:

在此输入图像描述

现在我想知道为什么组件的数据属性即使在显式设置为另一个值后也不会更新.尝试设置一个观察器$route来触发该reload方法,但没有骰子 - 该路由的每个后续负载确实重新发出了获取,并且控制台记录this.records为已填充(从获取内),但"真实" this.records仍然是一个空数组.

Swa*_*der 5

解决方案是jsfiddle方法,有一个扭曲.这部分:

reload: function () {
      fetch('/data/api', {
        method: 'get'
      }).then(function (response) {
        return response.json();
      }).then(function (response) {
        if (response.status == "success") {
          this.records = response.payload;
        } else {
          console.error(response.message);
        }
      }).catch(function (err) {
        console.error(err);
      });
    }
Run Code Online (Sandbox Code Playgroud)

在获取之后.bind(this)设置this.records值的部分中需要a ,如下所示:

reload: function () {
      fetch('/data/api', {
        method: 'get'
      }).then(function (response) {
        return response.json();
      }).then(function (response) {
        if (response.status == "success") {
          this.records = response.payload;
        } else {
          console.error(response.message);
        }
      }.bind(this)).catch(function (err) {
        console.error(err);
      });
    }
Run Code Online (Sandbox Code Playgroud)

这篇文章让我点击了它.

获得的经验:在现代JS中,始终牢记范围.