异步 Vue 生命周期

Dav*_*fti 3 vue.js

我的 Vue.js 应用程序有以下情况:

data() {
   return {
      data: []
   }
},

async created() {
   console.log('before async call')
   try {
      // async call ...
      console.log('after async call')
      this.data = // data from api call
   } catch (err) {
      // handle err
   }
},

mounted() {
   console.log('mounted')
   init(this.data)
}
Run Code Online (Sandbox Code Playgroud)

当我运行代码时,我得到:

before async call
mounted
after async call
Run Code Online (Sandbox Code Playgroud)

因此,init 方法(mounted 中的类构造函数)会使用空数组而不是来自 API 调用的数据进行调用。我想要的是同步执行事物,并且在数据可用之前不执行安装。我知道上面的问题是当包含异步代码时Vue如何执行生命周期,但是如何解决这样的问题呢?

And*_*hiu 6

asyncVue 中的生命周期是一种具有误导性的语法。

每个 Vue 生命周期只是一个触发器,用于运行您在特定时间放入的任何代码。

但 Vue 不会等待 Promise 解决并保留其他所有内容(与组件的生命周期相关),直到它发生为止。实际上,您所做的就是延迟放置在生命周期中的代码的执行,直到某些承诺得到解决。

为了让您更好地理解正在发生的事情,以下语法是等效的:

async created() {
  const data = await fetchSomeData(); 
  // rest of code depending on `data`
}
Run Code Online (Sandbox Code Playgroud)

等价的:

created() {
  fetchSomeData().then(data => {
    // rest of code depending on `data`
  });
}
Run Code Online (Sandbox Code Playgroud)

由于async生命周期是一种误导性的语法,因此在大型团队开发的应用程序中通常不鼓励使用它,而倾向于使用该.then()语法。这是为了避免代码实际运行时因误解而产生的小错误。例如,如果新开发人员将一些代码放入钩子中async(没有仔细查看钩子中的其余代码),则代码可能会比预期运行得晚,除非放置在任何await.


要修复您想要修复的任何错误,只需将无法渲染的内容包装起来,直到实际data解析为if(内部组件)或v-if(内部模板)。

典型用法示例:

computed: {
  someComputed() {
    if (this.data.length) {
      // returned when data has length
      return something
    }
    // returned when data has no length
    return somethingElse
  }
}
Run Code Online (Sandbox Code Playgroud)

或者:

<div v-if="data.length">
   <!-- markup depending on actual data... -->
</div>
<div v-else>
   loading...
</div>
Run Code Online (Sandbox Code Playgroud)

注意:computed上面的内容将自动对 的长度变化做出反应data(不需要 a watch),因为computed每当属性的内部反应引用改变值时,属性就会重新运行。正如您所期望的,它们会根据它们重新计算/重新渲染任何内容。对于 也是如此<v-if>。在内部,它们都使用所谓的 Vue 的“注入和反应性”