在nuxt3里useFetch封装一个api接口http请求

2022-03-31 16:54
椰子皮
22318
36
32
Vue

“ 在nuxt3里useFetch封装一个api接口http请求 ”

2023-04-04基于nuxt3.3.3更新

nuxt3使用了ts和vue3,nuxt3的使用下来,体验还是很不错的,那么如何在nuxt3里面封装一个http请求呢

相关文档:https://nuxt.com.cn/docs/api/composables/use-fetch

新建一个http.ts

以下是基于rc.8以上版本增加了createError,错误可以在error.vue中展示

复制代码
import { hash } from 'ohash'

// 后端返回的数据类型
export interface ResOptions<T> {
  data: T
  code?: number
  message?: string
}

/**
 * api请求封装
 * @param { String } url 请求地址
 * @param { Object } options useFtech第二个参数
 * @param { Object } headers 自定义header头, 单独设置headers区分请求参数,也好设置类型
 */
const fetch = async (url: string, options?: any, headers?: any) => {

  try {
    // 3.0正式版环境变量要从useRuntimeConfig里的public拿
    const { public: { VITE_API_HOST } } = useRuntimeConfig()
    const reqUrl = VITE_API_HOST + url // 你的接口地址

    // 设置key
    const key =  hash(JSON.stringify(options) + url)

    // 可以设置默认headers例如,token的获取最好用useState返回一个useCookie
    const customHeaders = { token: useToken().value, ...headers }

    const { data, error } = await useFetch(reqUrl, { ...options, key, headers: customHeaders })
    const result = data.value as ResOptions<any>
    console.log('useFetchResData: ', result)
    if (error.value || !result || (result && result.code !== 200)) {
      // 处理token失效的情况
      if (code === 401) {
        // token.value = ''
        await navigateTo('/login')
      }
      // 在客户端的时候抛出错误结果方便捕捉
      if (process.client) {
        return Promise.reject(result || error.value)
      }
      // 在服务端就直接渲染错误页面,需要设置一个error.vue接收错误信息
      throw createError({
        statusCode: 500,
        statusMessage: reqUrl,
        message: error.value?.message || '服务器内部错误',
      })
    }
    return result.data // 这里直接返回data或者其他的
  } catch (err) {
    console.log(err)
    return Promise.reject(err)
  }

}

export default class Http {

  get(url: string, params?: any, headers?: any) {
    return fetch(url, { method: 'get', params }, headers)
  }

  post(url: string, body?: any, headers?: any) {
    return fetch(url, { method: 'post', body }, headers)
  }

  put(url: string, body?: any, headers?: any) {
    return fetch(url, { method: 'put', body }, headers)
  }

  delete(url: string, body?: any, headers?: any) {
    return fetch(url, { method: 'delete', body }, headers)
  }
}

新建一个api文件夹,新建一个index.ts,其他的根据业务模块新建文件,index.ts用于导出其他模块,如图:

比如我想把文章相关的api都写在一个文件里,我们可以利用到js的继承,让api代码可读性更高,例如可以在article.ts里面写:

复制代码
import Http from '@/utils/http'

export default new class article extends Http {

  /**
   * 获取热门文章,自定义返回类型可以通过Promise<T>设置,不设置就是any
   */
  public getHot(): Promise<{ items: Array<{ id: number, name: string }>}> {
    return this.get('/app/v1/article/hotView')
  }

  /**
   * 获取文章详情
   * @param { Number } id 文章id
   */
  public getDetail(id: number) {
    return this.get('/app/v1/article/detail/' + id)
  }
}

如果类型太多,可以在api里面再建一个types,里面放对应模块的.d.ts类型

api/index.ts导出这些模块:

复制代码
import articleApi from '@/api/article'

export default {
  articleApi,
}

composables/index.ts中:

复制代码
import api from '@/api/index'

export const useApi = () => api

然后页面中使用:

复制代码
<script lang="ts" setup>
const { articleApi } = useApi()
// 返回的数据结构根据自己后端在api文件定义好,这里建议直接等于返回结果,不用再去定义类型了
const hots = await articleApi.getHot({ page: 1, size: 50 })
console.log(hots.items)

</script>
赏
支付宝微信
32
关注公众号获取更多内容
uniapp 长按longpress之后touchend touchcancel不触发不生效
nuxt3+vue3+typescript里写一个全局提示框toast插件
共有 21 条评论
发表评论
  • 111#10123
    2023-08-10 10:22
    四川省乐山市
    Windows 10
    Chrome

    code === 401 这里的code是什么意思,哪里来的呀

    回复
    • 椰子皮#10165
      2023-08-10 10:22
      四川省乐山市
      Windows 10
      Chrome

      后端返回给你的code

      回复
  • freezyh#10121
    2023-07-31 09:40
    广东省广州市天河区
    Windows 10
    Chrome

    useFetch 里面的配置选项key 好像起不来了作用,有和没有效果都一样,博主能举个例子么

    回复
  • rachel#10120
    2023-07-05 16:19
    上海市上海市普陀区
    Mac OS 10.15.7
    Chrome

    用了这个封装方法,刷新页面,报错 Error: A composable that requires access to the

    回复
  • lagaga#10119
    2023-06-25 14:47
    四川省成都市武侯区
    Windows 10
    Chrome

    setup顶层处理await,你如何抛错呢?

    回复
    • 椰子皮#10164
      2023-06-25 14:47
      四川省成都市武侯区
      Windows 10
      Chrome

      加try catch不就行了,你也可以再写个函数内部处理错误,再顶层await这个函数

      回复
  • creepre#10118
    2023-05-06 14:06
    云南省昆明市西山区
    Windows 10
    Chrome

    Http是构造函数,不new就能访问里面的方法?

    回复
    • 椰子皮#10163
      2023-05-06 14:06
      云南省昆明市西山区
      Windows 10
      Chrome

      需要new,感谢指正,已修改

      回复
  • 前端ss#10117
    2023-04-27 16:57
    北京市北京市东城区
    Windows 10
    Chrome

    首屏从后台请求数据渲染以后,页面通过@绑定的事件都没有被绑定,是什么原因?你们没有出现么?用官方原始写法不会

    回复
    • 椰子皮#10162
      2023-04-27 16:57
      北京市北京市东城区
      Windows 10
      Chrome

      就是客户端js被阻塞了吧,有个相关配置可以解决服务端加载太久

      回复
  • carefree#10116
    2023-04-12 13:43
    福建省福州市
    Windows 10
    Chrome

    有没有能隐藏后端请求api地址的方法

    回复
    • 椰子皮#10161
      2023-04-12 13:43
      福建省福州市
      Windows 10
      Chrome

      没有,异步都会被看到的,自己再加密就可以了

      回复
  • nuxt3#10115
    2023-04-09 17:09
    湖北省武汉市
    Mac OS 10.15.7
    Chrome

    您好,使用useFetch方法去请求, 默认是混合模式(ssr、csr),部署到生产后,首次请求该页面(或是刷新后),请求都为404;但是再从其他页面跳转到此页面(此时是csr吧),请求都正常。请教您问题可能出在哪里

    回复
    • 椰子皮#10160
      2023-04-09 17:09
      湖北省武汉市
      Mac OS 10.15.7
      Chrome

      检查请求是否在顶级await,就是要服务端渲染这个请求必须是顶级await

      回复
  • HELLO#10114
    2023-03-02 10:16
    广东省深圳市南山区
    Windows 10
    Chrome

    请问需要请求第三方服务器,怎么配置才不会跨域呢?

    回复
    • 椰子皮#10159
      2023-03-02 10:16
      广东省深圳市南山区
      Windows 10
      Chrome

      可以通过后端接口进行转发一下,或者直接用nuxt的server里面用node封装一个接口

      回复
  • 落落#10113
    2023-02-23 14:29
    北京市北京市朝阳区
    Windows 10
    Chrome

    请问为什么我的客户端有跨域问题

    回复
共 21 条 第 1-10 条
每页
10
条
  • 1
  • 2
  • 3
跳至
页 跳转
不支持canvas