必须在哪个 VueJS 生命周期钩子中调用异步 HTTP 请求?

Which VueJS lifecycle hook must Asynchronous HTTP requests be called in?

我想知道在呈现页面之前如何向我的服务器发送异步 GET 请求以检索数据并填充数据中的属性。我听说最好的方法是在 Vue js 提供的三个生命周期钩子之一中调用发送此请求的函数,这些钩子在呈现 DOM 之前运行。三者分别是beforeCreate()created()beforeMount()。理想情况下,该请求必须调用哪一个?为什么?

视情况而定。

This depends what you want, for a User Experience. Do you want the route to display immediately, but show a loading spinner on this routes content?

Or do you want to wait until data is fetched, THEN show the route? (which could give the illusion of a laggy application)

If you want to do the first way I mentioned, then you could do it in the created hook of your component.

https://forum.vuejs.org/t/what-is-the-best-hook-to-call-api-to-load-initialisation-data-for-a-component/15167/2

TL;DR in the general (and safe) case, use created().

Vue的初始化代码同步执行

从技术上讲,您在 beforeCreate()created()beforeMount() 中 运行 的任何异步代码只会在 all 个钩子完成。见演示:

new Vue({
  el: '#app',
  beforeCreate() {
    setTimeout(() => { console.log('fastest asynchronous code ever') }, 0);
    console.log('beforeCreate hook done');
  },
  created() {
    console.log('created hook done');
  },
  beforeMount() {
    console.log('beforeMount hook done');
  },
  mounted() {
    console.log('mounted hook done');
  }
})
<script src="https://unpkg.com/vue/dist/vue.min.js"></script>
<div id="app">
  Check the console.
</div>

换句话说,如果你在 beforeCreate() 中调用 Ajax,无论 API 响应多快,响应只会在稍后处理,在created()已执行。


那么,您应该根据什么来做出决定?

如上所述,Vue和React都存在的关键问题是,如果你发起网络请求,数据在组件创建之前到达,没有实例可以设置数据。

beforeCreated 类似于 React 的 componentWillMount。您通常不想在这里执行网络请求,因为您可能会在组件存在之前取回数据。就像设置this.data = data但是没有组件,所以this还不存在

React 中更好的地方是 componentDidMount,但我们不关心那个。在Vue中,更好的地方是created,因为组件已经创建,所以this存在。

这是一个例子:

<template>
  <div>
    <span v-if="error">{{ error }}</span><br>
    I like:<br>
    {{ data }}
  </div>
</template>

<script>
export default {
  data() {
    return {
      data: '',
      error: undefined,
    }
  },

  async created() {
    try {
      const response = await axios.get('/endpoint/stuff')
      this.data = response
    } catch (err) {
      this.error = err
    }
  },
}
</script>

vue-router 文档对从组件渲染所需的服务器检索数据时使用的模式提供了一些建议(link 见底部)。

为了确定在哪里执行 GET 请求,他们首先询问您是否要导航到路由 before async GET request is initiated or after

如果你想获取数据然后导航到路由(导航前)那么文档建议在传入的 beforeRouteEnter() 守卫中执行异步请求组件确保在完成异步数据请求后在 beforeRouteEnter() 中调用 next()。如果您选择此模式,您将希望显示某种加载指示器,因为在获取数据之前不会导航到组件的 route/rendering。

如果您想导航到路线然后发起请求(导航后)然后文档建议在 created() 挂钩中执行请求并使用 v-if 有条件地显示组件正在加载、发生错误或数据到达后的视图。

强烈建议查看文档,它们有代码示例并且写得很好。 https://router.vuejs.org/guide/advanced/data-fetching.html#fetching-before-navigation