Nuxt.js supports traditional Vue patterns for loading data in your client-side app, such as fetching data in a component’s mounted() hook. Universal apps, however, need to use Nuxt.js-specific hooks to be able to render data during server-side rendering. This allows your page to render with all of its required data present.
Nuxt.js支持传统的Vue模式在客户端加载数据,例如在组件的mounted()钩子里获取数据。但是,通用应用程序需要使用 Nuxt.js-特定钩子才能在服务端渲染数据。这允许你的页面呈现其所有必须的所有数据。

Nuxt has two hooks for asynchronous data loading:
Nuxt有两个用于异步数据加载的钩子:

  • The fetch hook (Nuxt 2.12+). This hook can be placed on any component, and provides shortcuts for rendering loading states (during client-side rendering) and errors.
  • The asyncData hook. This hook can only be placed on page components. Unlike fetch, this hook does not display a loading placeholder during client-side rendering: instead, this hook blocks route navigation until it is resolved, displaying a page error if it fails.
  • fetch钩子(nuxt 2.12+)。这个钩子可以放在任意组件中,并为渲染加载状态(在服务端渲染期间)和错误提供快捷方式。
  • asyncData钩子。这个钩子只能放在page组件中。和fetch不同,这个钩子在客户端渲染时没有加载占位符,这个钩子会阻断路由导航,直到它被解决,如果失败展示页面错误。

In versions of Nuxt before 2.12, the fetch hook worked much like asyncData does today. This functionality is still supported today for backwards-compatibility: if a context argument is accepted in your fetch(), it will be considered a “legacy” fetch hook. This functionality is deprecated, and should be replaced with either asyncData(context) or an anonymous middleware using middleware(context).

在 2.12 之前的 Nuxt 版本中,fetch hook 的工作方式与今天的 asyncData 非常相似。为了向后兼容,今天仍然支持此功能:如果在您的 fetch() 中接受上下文参数,它将被视为“传统”获取挂钩。此功能已弃用,应替换为 asyncData(context) 或使用 middleware(context) 的匿名中间件。

These hooks can be used with any data fetching library you choose. We recommend using @nuxt/http or @nuxt/axios for making requests to HTTP APIs. More information about these libraries, such as guides for configuring authentication headers, can be found in their respective documentation.
这些钩子可以被用在任何你选择的数据获取库。我们推荐使用 @nuxt/http 或者 @nuxt/axios 发送请求到HTTP APIs. 更多关于这些库的信息,例如配置授权头指南,能在它们的各自文档中找到。

If you define fetch or asyncData inside a mixin and also have it defined in a component/page, the mixin function will be overwritten instead of called. 如果你定义fetch或者 asyncData在一个混合并在component/page也有它的定义,这个混合函数将被覆盖而不是被调用


The fetch hook

This hook is only available for Nuxt 2.12 and later. 这个钩子仅适用于Nuxt2.12或者更高版本

fetch is a hook called during server-side rendering after the component instance is created, and on the client when navigating. The fetch hook should return a promise (whether explicitly, or implicitly using async/await) that will be resolved:
fetch是一个在组件实例被创建之后,服务端渲染期间被调用的钩子 ,并在客户端导航时。fetch 钩子应该返回一个被解析的promise(无论显式实或者隐示使用async/await)

  • On the server before the initial page is rendered
  • On the client some time after the component is mounted

It exposes $fetchState at the component level with the following properties:

  • pending is a Boolean that allows you to display a placeholder when fetch is being called on client-side.
  • error is either null or an Error thrown by the fetch hook
  • timestamp is a timestamp of the last fetch, useful for caching with keep-alive

  • 在服务端,初始化页面被渲染之前

  • 在客户端,在组件被挂在之后一段时间

它暴露$fetchState在组件级别,和下面属性:

  • pending一个布尔值,当在客户端fetch被调用时允许你显示占位符
  • error要么是null要么是fetch钩子抛出Error
  • timestamp是最后获取的时间戳,对于保持活动状态的缓存很有用

For static hosting, the fetch hook is only called during page generation, and the result is then cached for use on the client. To avoid cache conflicts, it may be necessary to specify a name for your component, or alternatively provide a unique fetchKey implementation. 对于静态托管,仅在页面生成期间调用 fetch 钩子,然后将结果缓存以供客户端使用。为避免缓存冲突,可能需要为您的组件指定一个名称,或者提供唯一的 fetchKey 实现。

In addition to fetch being called by Nuxt, you can manually call fetch in your component (to e.g. reload its async data) by calling this.$fetch().
除了 Nuxt 调用 fetch 之外,您还可以通过调用 this.$fetch() 在组件中手动调用 fetch(例如重新加载其异步数据)。

  1. <template>
  2. <p v-if="$fetchState.pending">Fetching mountains...</p>
  3. <p v-else-if="$fetchState.error">An error occurred :(</p>
  4. <div v-else>
  5. <h1>Nuxt Mountains</h1>
  6. <ul>
  7. <li v-for="mountain of mountains">{{ mountain.title }}</li>
  8. </ul>
  9. <button @click="$fetch">Refresh</button>
  10. </div>
  11. </template>
  12. <script>
  13. export default {
  14. data() {
  15. return {
  16. mountains: []
  17. }
  18. },
  19. async fetch() {
  20. this.mountains = await fetch(
  21. 'https://api.nuxtjs.dev/mountains'
  22. ).then(res => res.json())
  23. }
  24. }
  25. </script>

You can access the Nuxt context within the fetch hook using this.$nuxt.context.
你可以在fetch钩子里使用this.$nuxt.context访问 Nuxt context

Options

fetchOnServer: Boolean or Function (default: true), call fetch() when server-rendering the page
fetchOnServer:布尔值或者函数(默认:true), 服务端渲染页面时调用 fetch()

fetchDelay: Integer (default: 200), set the minimum executing time in milliseconds (to avoid quick flashes)
fetchDelay: 数值(默认:200),以毫秒为单位设置最小执行时间(防止闪烁)

When fetchOnServer is falsy (false or returns false), fetch will be called only on client-side and $fetchState.pending will return true when server-rendering the component.
当fetchOnServer是假的时(false或者返回false),fetch 将仅在客户端被调用,并且当服务端渲染组件时 $fetchState.pending将返回true。

  1. export default {
  2. data() {
  3. return {
  4. posts: []
  5. }
  6. },
  7. async fetch() {
  8. this.posts = await fetch('https://api.nuxtjs.dev/posts').then(res =>
  9. res.json()
  10. )
  11. },
  12. // call fetch only on client-side
  13. fetchOnServer: false
  14. }

Listening to query string changes

监听查询字符串变化
The fetch hook is not called on query string changes by default. To watch for query changes you can add a watcher on $route.query and call $fetch:
默认查询字符串变化时 fetch钩子不被调用。 监视查询变化,你能增加一个监视器在 $route.query并调用$fetch:

  1. export default {
  2. watch: {
  3. '$route.query': '$fetch'
  4. },
  5. async fetch() {
  6. // Called also on query changes
  7. }
  8. }

。。。。

Async Data

**asyncData** is only available for pages and you don’t have access to **this** inside the hook. asyncData 仅适用于pages 并且你不能在这个钩子里面接收this

**asyncData** is another hook for universal data fetching. Unlike **fetch**, which requires you to set properties on the component instance (or dispatch Vuex actions) to save your async state, **asyncData** simply merges its return value into your component’s local state. Here’s an example using the @nuxt/http library:
asyncData是通用数据请求的另一个钩子,不像fetch, 这个需要你在组件实例中设置属性(或者派发vuex actions)保存你的异步状态,asyncData简单地合并它的返回值到你的组件的本地状态。这是一个使用@nuxt/http 库的案例:

  1. <template>
  2. <div>
  3. <h1>{{ post.title }}</h1>
  4. <p>{{ post.description }}</p>
  5. </div>
  6. </template>
  7. <script>
  8. export default {
  9. async asyncData({ params, $http }) {
  10. const post = await $http.$get(`https://api.nuxtjs.dev/posts/${params.id}`)
  11. return { post }
  12. }
  13. }
  14. </script>

Unlike fetch, the promise returned by the asyncData hook is resolved during route transition. This means that no “loading placeholder” is visible during client-side transitions (although the loading bar can be used to indicate a loading state to the user). Nuxt will instead wait for the asyncData hook to be finished before navigating to the next page or display the error page).
不像fetch,promise在路由转换过程中通过asyncData钩子被解决被返回。这意味着在客户端转换时没有“加载占位符”显示(虽然加载条被用于向用户展示加载状态)Nuxt 将在导航到下一页或显示错误页面之前等待 asyncData 钩子完成)。

This hook can only be used for page-level components. Unlike fetch, asyncData cannot access the component instance (this). Instead, it receives the context as its argument. You can use it to fetch some data and Nuxt.js will automatically shallow merge the returned object with the component data.
这个钩子只能被用于page级的组件,与fetch不同,asyncData不能访问组件实例(this)。相反,它接受context作为它的参数。你能使用它去获取一些数据并且Nuxt.js 会自动将返回的对象与组件数据进行浅合并。

In the upcoming examples, we are using @nuxt/http which we recommend for fetching data from an API.
在接下来的例子,我们会使用 @nuxt/http,这是我们推荐从API获取数据。


Async data in components?

Because components do not have an asyncData method, you cannot directly fetch async data server side within a component. In order to get around this limitation you have three basic options:
因为组件没有asyncData方法,你不能在组件里直接请求异步数据。为了绕过这个限制,你有三个基本选择:

  1. Use the new fetch hook that is available in Nuxt 2.12 and later versions.
  2. Make the API call in the mounted hook and set data properties when loaded. Downside: Won’t work for server side rendering.
  3. Make the API call in the asyncData method of the page component and pass the data as props to the sub components. Server rendering will work fine. Downside: the asyncData of the page might be less readable because it’s loading the data for other components.

    1. 使用心得fetch钩子,它适用于nuxt2.12及之后的版本。
      2. 在mounted钩子中使用api调用并且当加载后设置data属性. 缺点:不能在服务端工作
      3. 在页面组件的asyncData方法中使用api调用,并且传递data作为props给子组件。服务端渲染将很好的工作。缺点:页面的asyncData可能成不太可读,因为它为其他组件加载数据。