NuxtJS的 AsyncData 和 Fetch 使用详解

发布于 2022年 01月 12日 09:44

asyncData

简介

asyncData 可以用来在客户端加载 Data 数据之前对其做一些处理,也可以在此发起异步请求,提前设置数据,这样在客户端加载页面的时候,就会直接加载提前渲染好并带有数据的 DOM,完成服务端渲染,有助于搜索引擎的抓取。

注意事项:

  1. 由于在客户端创建实例化之前加载,所以不能使用 this,钩子提供一个参数,可以获取上下文对象({isDev, route, store, env, params, query, req, res, redirect, error}等),从而做一些简单操作。
  2. 只能在路由页面组件中使用(每次加载页面都会调用),在自定义组件中无效。
  3. 返回的数据最终将与 data 数据合并,为了保证不发生页面渲染错误,返回的键应事先在 data 里声明好(如果 template 中没有使用所需属性,则并不必声明)。
  4. 钩子在路由转换期间解析,所以在 return 之前会一直等待内部逻辑处理,会阻滞页面加载。如果要抛出异常,可以使用参数提供的 error 方法。
  5. asyncData 必须返回一个对象(Object),否则将导致页面无法加载。

使用方式 (Javascript)

按照官网说明 asyncData 有三种使用方式,
使用示例:

  • 返回 Promise 对象的方式

export default { asyncData({ params }) { return axios.get(`https://my-api/posts/${params.id}`).then(res => { return { title: res.data.title }; }); } };
  • 使用 async/await 的方式

export default { async asyncData({ params }) { const { data } = await axios.get(`https://my-api/posts/${params.id}`); return { title: data.title }; } };
  • 使用回调函数的方式(v2.12 弃用)

export default { asyncData({ params }, callback) { // asyncData提供两个参数(已弃用) axios.get(`https://my-api/posts/${params.id}`).then(res => { callback(null, { title: res.data.title }); }); } };

使用方式 (Typescript)

Nuxt 的 ts 版组件,有三种构建风格,
使用示例:

  • 选项式 API

export default Vue.extend({ // async/await方式 async asyncData({ params }) { const { data } = await axios.get(`https://my-api/posts/${params.id}`); return { title: data.title }; } // Promise方式 /* asyncData({ params }) { return axios.get(`https://my-api/posts/${params.id}`).then(res => { return { title: res.data.title } }) }, */ });
  • 类式组件

    类式组件应在装饰器内传入该方法,而不是在 Class 内使用。
import { Component, Vue } from "vue-property-decorator"; @Component({ async asyncData({ params }) { const { data } = await axios.get(`https://my-api/posts/${params.id}`); return { title: data.title }; } }) export default class PageIndex extends Vue { title: string; }
  • 组合式 API(v3.0 以上)

import { defineComponent, ref } from "@vue/composition-api"; import { useAsyncData } from "#app"; export default defineComponent({ async setup() { const { data } = await useAsyncData("count", () => $fetch("/api/count")); return { title: data.title }; } });

fetch

简介

旧版本的 fetch 在组件实例化之前运行,无法使用 this,如同 asyncData,提供了可查询长下文的参数,且亦只能在页面级组件中使用,并且只能通过上下文参数操作 store 状态的数据,而不能设置或合并 data 数据。

注:由于 fetch 钩子的功能在 nuxt v2.12 以上版本作了较大调整,所以下文只记录新的使用方式。

fetch 用来在组件加载时预先提取数据,运行于组件实例创建之后(created)页面渲染完成之前(mounted),并且可以用于任何组件(包括路由页面或自定义组件)和随时通过$fetch 方法主动更新数据。

使用方式

默认选项式组件:

export default { fetchOnServer: false, //可以通过内置的fetchOnServer属性,来关闭服务端fetch行为。 async fetch() { const { data } = await axios.get( `https://my-api/posts/${this.$route.params.id}` ); this.title = data.title; } };

Typescript 类式组件:

import { Component, Vue } from "vue-property-decorator"; @Component export default class PageBarIndex extends Vue { async fetch(this: PageBarIndex) { const { data } = await axios.get( `https://my-api/posts/${this.$route.params.id}` ); this.title = data.title; } }

asyncData 和 fetch 的区别

  • 组件限制
    • asyncData 仅限于页面级组件。
    • fetch 可用于任意组件。
  • 获取上下文
    • asyncData 不可以使用 this,只能通过回调参数获取上下文对象。
    • fetch 可以使用 this。
  • 数据操作
    • asyncData 通过 return 合并 data 数据。
    • fetch 可以使用 this 直接修改赋值。
  • 调用时机
    • asyncData 只在页面创建前调用。
    • fetch 在页面实例创建后调用,并可以通过$fetch 方法随时触发,$fetchState.timestam 属性可以获取最后一次触发的时间戳。
  • 错误处理
    • asyncData 通过 error 参数抛出错误,但并不会在页面显示异常。
    • fetch 可以使用 throw new Error()来抛出异常,在页面调用$fetchState.error 方法获取异常状态。
  • 页面渲染
    • asyncData 在页面创建前填充数据。
    • fetch 可通过 fetchOnServer 属性设置是否允许在服务端获取数据,设置为 false 将可以在渲染数据时通过$fetchState.pendinding 获取加载状态。

生命周期示意图

生命周期示意图

__EOF__

本文作者余以为
本文链接https://www.cnblogs.com/China-Dream/p/15667561.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!

推荐文章