Nuxt3实战系列之网络请求篇

Nuxt3提供了4种方式使得我们可以异步获取数据

  • useAsyncData
  • useLazyAsyncData (useAsyncData+lazy:true)
  • useFetch
  • useLazyFetch (useFetch+lazy:true)

4种方式中,其实核心的就是useAsyncDatauseFetch。这两个方法不同于Nuxt2中的asyncDatafetch。接下来我们先来好好分析下这两个方法。

useAsyncData

我们知道,在Nuxt2中,asyncData方法类似于一个生命周期函数,它在服务端或路由更新之前被调用。方法的参数是当前页面的上下文对象,我们一般是利用 asyncData方法来获取数据并返回给当前组件,以避免请求放在客户端执行时带来的数据延迟出现问题。

export default {
  data() {
    return { project: 'default' }
  },
  asyncData(context) {
    return { project: 'nuxt' }
  }
}

在Nuxt3中,useAsyncData可以看做是异步获取数据场景的一个封装,而且变成了一个主动调用函数,原则上可以在任何时机调用。

// 用法
const {
  data: Ref,// 返回的数据结果
  pending: Ref,// 是否在请求状态中
  refresh: (force?: boolean) => Promise,// 强制刷新数据
  error?: any // 请求失败返回的错误信息
} = useAsyncData(
  key: string, // 唯一键,确保相同的请求数据的获取和去重
  fn: () => Object,// 一个返回数值的异步函数
  options?: { lazy: boolean, server: boolean }
  // options.lazy,是否在加载路由后才请求该异步方法,默认为false
  // options.server,是否在服务端请求数据,默认为true
  // options.default,异步请求前设置数据data默认值的工厂函数(对lazy:true选项特别有用)
  // options.transform,更改fn返回结果的函数
  // options.pick,只从数组中指定的key进行缓存
)

从api的设计中可以看出,useAsyncData没有限制我们发起网络请求的方式,同时它还暴露了请求状态,增加了刷新控制,以及对重复获取数据的去重控制等。
使用示例如下:



useFetch

在Nuxt2中,fetch 方法用于在渲染页面前填充应用的状态树(store)数据, 与 asyncData 方法类似,不同的是它不会设置组件的数据。



在Nuxt3中,useFetch实际上是对useAsyncData$fetch的封装,提供了一个更便捷的封装方法。它相比useAsyncData, 主要做了以下两点处理:

  1. 它会根据URL和fetch参数自动生成一个key,同时推断出API的响应类型。也就是说不用手动指定key了。
  2. 它实现了网络请求的具体方式,使用$fetch发起请求,也就是说不需要再手动去实现网络请求的逻辑了。

    //useFetch用法
    const {
      data: Ref,
      pending: Ref,
      refresh: (force?: boolean) => Promise,
      error?: any
    } = useFetch(url: string, options?)
    // options (继承自 unjs/ofetch options以及 AsyncDataOptions)
    // 下边的这些参数是useAsyncData的options中没有的
    // options.method: 请求方式
    // options.query: url路径参数
    // options.params: query参数的别名
    // options.body: 请求体参数,
    // options.headers: 请求头的配置
    // options.baseURL: 请求的基础Url地址

    实战应用

    我们不难发现,useFetch已经具备了网络请求的所有核心功能,虽然该Api主要用于在服务端请求,但它也是做了客户端请求的支持的,只要稍加封装改动,就可以同时用于服务端请求和客户端请求的场景。这样我们也就不用额外再引入像Axios这样的请求库了。

    场景1: 如何处理对于带错误码的数据响应

    通常我们的接口都不是直接返回数据,而是带了一个错误码和错误信息的对象,比如这样:

    // response:
    {
      data: {age: 1},
      code: 1
    }

    在这样的返回结构下,useFetch拿到的数据并不是我们真实想要的数据

    const { data } = await useFetch('/api/user/info', {
      method: 'get'
    })
    console.log(data) // 此时data是一个Ref包裹的对象{ data: {age: 1}, code: 1 }
    const userInfo = unref(data).data //获取真正的数据需要先unref后再去获取data

    所以,我们希望能在接口返回时对数据做一下转换,这里其实useFetch提供了相关的option参数,我们可以这样修改

    const { data: userInfo} = await useFetch('/api/user/info', {
      method: 'get',
      // 处理方式1
      onResponse({ response }) {
     response._data = {
       ...response._data.data,
     }
      },
      // 处理方式2
      // transform: (res) => {
      //   return res.data
      // },
    })

    场景2: 如何只在客户端侧发起请求

    这样的场景一般用于使用静态化构建部署,但是页面上有些内容是不能在构建时静态化的。这时可以利用server:false参数

    // 异步获取当前用户信息
    const { data: userinfo } = await useMyFetch('/api/auth/userinfo', {
      server: false
    })
    

    注意: 这种情况下,如果想在script内直接获取到userinfo的内部值,是获取不到的!官方文档也做了对应的说明:

    if you have not fetched data on the server (for example, with server: false), then the data will not be fetched until hydration completes. This means even if you await useFetch on client-side, data will remain null within

你可能感兴趣的:(Nuxt3实战系列之网络请求篇)