首页 > 解决方案 > 正确设置 Vue.js 方法来处理 Axios 异步请求

问题描述

我有 Vue.js 应用程序,它使用 Axios 从 API 获取一些复杂数据,然后可视化这些数据。我的代码与此类似:

{
  data: () => ({
    data: null,  // or Object, it doesn't matter now
    loading: false,
    errored: false,
    loadingMessage: ''
  }),
  methods: {
    loadData: function() {
      this.loading = true;
      this.loadingMessage = 'Fetching Data';
      axios.get('api/url/').then((response) => {
        this.data= response.data;  // or this.$set(this, 'data', response.data), it doesn't matter now
        this.loadingMessage = 'Process Data';
        this.processData();
      })
      .catch(function () {
        this.errored= true;
      })
      .then(function () {
        this.loading = false;
      })
    },
    processData: function() {
        // process data
    }
  }
}

然后我点击模板中的按钮,这个按钮调用loadData()函数。它工作正常,但获取数据需要一些时间,处理也需要一些时间,并且 Vue 仅在 axios 请求完成时更改模板和变量。所以我只看到Fetching Datamessage 而不是Process Data.

我如何向用户展示现在处理数据的哪个阶段?也许我应该调用 in 中的processData()函数watch methods,但这对我来说似乎有点矫枉过正。

更新

我结束了setTimeout()包装。请看下面我的回答。

标签: vue.jsasynchronousaxios

解决方案


Vue 有一个名为 的函数nextTick,它是一个异步函数,基本意思是“在下一次视觉更新后执行以下代码”。如果我有这样的视觉更新,我通常会使用这种方法。

我认为您示例中的代码如下所示:

axios
  .get('api/url/')
  .then((response) => {
    this.data= response.data;
    this.loadingMessage = 'Process Data';
    return this.$nextTick();
  })
  .then(() => {
    this.processData();
  })
  .catch (etc ...  

我不完全确定。我通常在启用 webpack/babel 的环境中工作,在这种情况下,我只需编写整个函数async并编写:

async function fn() {
  const response = await axios.get('api/url/');
  this.data = response.data;
  this.loadingMessage = 'Process Data';
  await this.$nextTick();
  this.processData();
}

推荐阅读