理解异步数据

asyncData 方法允许我们异步地获取数据并在组件初始化之前在服务器端渲染它。这是一个额外的、仅在 Nuxt 中可用的方法。这意味着你不能在 Vue 中使用它,因为 Vue 没有这个默认方法。Nuxt 总是在渲染页面组件之前执行这个方法。对于使用这个方法的页面,它会在服务器端执行一次,然后当通过使用 <nuxt-link> 组件生成的路由重新访问该页面时,它会在客户端执行。Nuxt 会将 asyncData 方法返回的数据与来自 data 方法或 data 属性的组件数据合并。这个方法接收 context 对象作为第一个参数,如下所示:

export default {
  asyncData (context) {
    // ...
  }
}

请记住,这个方法总是在页面组件初始化之前执行,因此我们无法通过 this 关键字在这个方法内部访问组件实例。有两种不同的使用方式;让我们在接下来的章节中探讨它们。

返回一个 Promise

我们可以在 asyncData 方法中使用 Promise 对象,通过返回 Promise,例如:

// pages/returning-promise.vue
asyncData (context) {
  const promise = new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('Hello World by returning a Promise')
    }, 1000)
  })
  return promise.then((value) => {
    return { message: value }
  })
}

在上面的代码中,Nuxt 将等待 1 秒钟,直到 Promise 被解析,然后才会使用 'Hello World by returning a Promise' 渲染页面组件。

使用 async/await

我们也可以在 asyncData 方法中使用 async/await 语句,例如:

// pages/using-async.vue
async asyncData (context) {
  const promise = new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('Hello World by using async/await')
    }, 2000)
  })
  const result = await promise
  return { message: result }
}

在上面的代码中,Nuxt 将等待 2 秒钟,直到 Promise 被解析,然后才会使用 'Hello World by using async/await' 消息渲染页面组件。使用 async/await 语句是一种编写异步 JavaScript 代码的新方法。它构建在 Promise 对象之上,并使我们的异步代码更具可读性。我们将在本书中经常使用这个语句。

合并数据

正如我们之前提到的,来自 asyncData 方法的异步数据将与来自 data 方法或 data 属性的组件数据合并。这意味着,如果你在组件的 data 中设置了一些默认数据,并且这些数据与 asyncData 方法中的对象键相同,那么它们将被 asyncData 方法的结果覆盖。这里有一个例子:

// pages/merging-data.vue
<p>{{ message }}</p>
<script>
export default {
  data () {
    return { message: 'Hello World' }
  },
  asyncData (context) {
    return { message: 'Data Merged' }
  }
}
</script>

在上面的代码中,Nuxt 将合并这两组数据,你将在屏幕上看到以下结果:

<p>Data Merged</p>

你可以在我们的 GitHub 仓库的 /chapter-8/nuxt-universal/koa-nuxt/understanding-asyncdata/ 目录下找到这些示例。

接下来,我们将在下一节中了解如何利用我们可以从 asyncData 方法访问的 context 对象。