【问题标题】:VueJS async component data and promisesVueJS 异步组件数据和承诺
【发布时间】:2017-01-04 21:49:23
【问题描述】:

试用 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);
        });
      }
    }
  }
};

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

我是不是走错了路?一旦完全获取数据records 属性以更新它的方法是什么?有没有办法强制代码停止,直到承诺解决(有效地使其同步)?无论如何,如果没有数据,该组件将毫无用处,因此无论如何都要等待一段时间才能使用它。

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

(我知道我可以使用非承诺 ajax 调用的 XHR/jQuery 方法来执行此操作,但我想学习如何使用 fetch 来执行此操作)


更新:我尝试定义一个 created 钩子,以及一个加载数据的方法,like this 但没有骰子 - 在我自己的实验中,records 属性在加载后无法更新。即使数据被成功获取(成功登录到控制台),它也不会改变。

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


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

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

【问题讨论】:

    标签: javascript asynchronous promise vue.js vue-component


    【解决方案1】:

    解决方案是 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);
          });
        }
    

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

    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);
          });
        }
    

    This post 是它吸引我的原因。

    经验教训:在现代 JS 中,始终牢记范围。

    【讨论】:

      猜你喜欢
      • 2018-09-07
      • 2018-07-01
      • 2015-10-09
      • 1970-01-01
      • 2014-05-04
      • 2018-07-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多