iT邦幫忙

0

Nuxt3 封裝Api問題

  • 分享至 

  • xImage

大家好,
近期再練習Nuxt3遇到了2個小問題,

  1. 在pages要如何使用pending()﹑refresh()?
  2. 將Api參數或ApiKey亂打,為何在Http.ts的error永遠都是null?

以下為封裝步驟,希望能有前輩指導
步驟一 創建useHttp.ts

// /utils/useHttp.ts

import { hash } from 'ohash'
export interface ResOptions<T> {
  data?: T
  code?: number
  msg?: string
}

const fetch = (url: string, options?: any, headers?: any): Promise<any> => {
  const { public: { VITE_API_HOST } } = useRuntimeConfig()
  const reqUrl = VITE_API_HOST + url
  const key = hash(JSON.stringify(options) + url)
  const customHeaders = { token: useCookie('token').value, ...headers }
  return new Promise((resolve, reject) => {
    useFetch(reqUrl, { ...options, key, headers: customHeaders }).then(({ data, error }) => {
    console.log(error.value) //Error值永遠都是null
      if (error.value) {
        reject(error.value)
        return
      }
      const value: ResOptions<any> = data.value
      console.log('useFetchResData: ', value)
      if (!value) {
        throw createError({
          statusCode: 500,
          statusMessage: reqUrl,
          message: 'xxxxx',
        })
      } else {
        resolve(value)
      }
    }).catch((err: any) => {
      console.log(err)
      reject(err)
    })
  })
}

export default class Http {

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

  post (url: string, params?: any, headers?: any): Promise<any> {
    return fetch(url, { method: 'post', params }, headers)
  }

  put (url: string, params?: any, headers?: any): Promise<any> {
    return fetch(url, { method: 'put', params }, headers)
  }

  delete (url: string, params?: any, headers?: any): Promise<any> {
    return fetch(url, { method: 'delete', params }, headers)
  }
}

步驟二 分類管理api

// composables/index.ts

import Http from '@/utils/http'

export const useGetTags = (params?: { size?: number, page?: number }, headers: any) => {
  return Http.get('/app/v1/tags', params, headers)
}

步驟三 /pages/index.vue

<script lang="ts" setup>
const tags = await useGetTags({ page: 1, size: 10 })
console.log(tags)
</script>
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 個回答

1
pblaten
iT邦新手 3 級 ‧ 2023-01-11 09:52:50
最佳解答

你好~
在第二步驟 分類管理api 的部分少了return,所以沒有回傳值。
可以做下面兩種更改:
一、在函式的大括號裡補上return

export const getTag = async (params: TagParams) => {
  return await useHttp.get('/app/v1/tags', params)
}

二、單一運算/呼叫,審略大括號

export const getTag = async (params: TagParams) => await useHttp.get('/app/v1/tags', params)
jim55167 iT邦新手 4 級 ‧ 2023-01-13 14:09:52 檢舉

前輩您好,方問另外請教兩個問題嗎?

  1. 封裝後要如何在Pages使用pending()﹑refresh()?
  2. 將Api參數或ApiKey亂打,為何在Http.ts的error永遠都是null?
pblaten iT邦新手 3 級 ‧ 2023-01-16 12:22:36 檢舉

jim55167,以下是我目前的理解,僅參考:
1.
先將useFetch中的pending, refresh()定義出來

await useFetch(reqUrl, { ...options, key, headers: customHeaders }).then(({ data, pending, refresh, error }) => {}

定義一個新的interface,將data, pending, refresh()封裝成新的物件

export interface IRes {
  data: any;
  pending: boolean;
  refresh(): Promise<void>;
}

封裝的新物件進行回傳:

const res_target: IRes = {
  data: value,
  pending: pending.value,
  refresh: refresh,
};
resolve(res_target);

將class Http方法中的Promise泛型,改成新定義的interface

get(url: string, params?: any, headers?: any): Promise<IRes> {}

在官方文件中useFetch的error的定義是:

error: an error object if the data fetching failed.
error: 資料獲取失敗時回傳的物件。

這邊的error.value是null,代表你的Api是有打通的。這就要看你的Api在Api參數或ApiKey亂打的情況下是怎麼處理的,再根據Api的處理模式進行錯誤處理。

0
greenriver
iT邦研究生 5 級 ‧ 2023-01-11 08:23:07

步驟五改成

const tags = async()=>{
    let resData = await TagApi.getTag({Cate:"台積電",Sp: 20});
}
tags()
greenriver iT邦研究生 5 級 ‧ 2023-01-11 08:28:41 檢舉

await 必須在 async 裡面才行

我要發表回答

立即登入回答