コンテンツへスキップ

useFetch

カテゴリ
エクスポートサイズ
2.42 kB
最終変更日
先週

リアクティブなFetch APIは、リクエストの中断、リクエストの発信前のインターセプト、URL変更時の自動リフェッチ、そして事前定義されたオプションを使用した独自のuseFetchの作成を可能にします。

Vue Schoolの無料ビデオレッスンでuseFetchを学びましょう!

ヒント

Nuxt 3で使用する場合、この関数はNuxtの組み込み関数useFetch()を優先して自動インポートされません。VueUseの関数を用いる場合は、明示的にインポートしてください。

デモ

useFetchの様々な機能をテストするために、以下のURLを使用できます。
通常のリクエスト: https://httpbin.org/get
リクエストの中断: https://httpbin.org/delay/10
レスポンスエラー: http://httpbin.org/status/500
isFinished: false
isFetching: false
canAbort: false
statusCode: null
error: null
data: null

使用方法

基本的な使用方法

useFetch関数は、URLを指定するだけで使用できます。URLは文字列または`ref`のいずれかです。`data`オブジェクトにはリクエストの結果が、`error`オブジェクトにはエラーが、`isFetching`オブジェクトにはリクエストの読み込み状況が含まれます。

TypeScript
import { useFetch } from '@vueuse/core'

const { isFetching, error, data } = useFetch(url)

非同期的な使用方法

useFetchは、通常のfetchと同様にawaitすることもできます。コンポーネントが非同期である場合、それを使用するコンポーネントは``タグでラップする必要があることに注意してください。公式Vue 3ドキュメントでSuspense APIの詳細を確認できます。

TypeScript
import { useFetch } from '@vueuse/core'

const { isFetching, error, data } = await useFetch(url)

URL変更時のリフェッチ

URLパラメータに`ref`を使用すると、useFetch関数はURLが変更されたときに自動的に別のリクエストをトリガーします。

TypeScript
const url = ref('https://my-api.com/user/1')

const { data } = useFetch(url, { refetch: true })

url.value = 'https://my-api.com/user/2' // Will trigger another request

リクエストの即時実行を防ぐ

`immediate`オプションをfalseに設定すると、`execute`関数が呼び出されるまでリクエストの実行が開始されません。

TypeScript
const { execute } = useFetch(url, { immediate: false })

execute()

リクエストの中断

useFetch関数の`abort`関数を使用してリクエストを中断できます。`canAbort`プロパティは、リクエストを中断できるかどうかを示します。

TypeScript
const { abort, canAbort } = useFetch(url)

setTimeout(() => {
  if (canAbort.value)
    abort()
}, 100)

`timeout`プロパティを使用して、リクエストを自動的に中断することもできます。指定されたタイムアウトに達すると、`abort`関数が呼び出されます。

TypeScript
const { data } = useFetch(url, { timeout: 100 })

リクエストのインターセプト

`beforeFetch`オプションを使用すると、リクエストが送信される前にインターセプトし、リクエストオプションとURLを変更できます。

TypeScript
const { data } = useFetch(url, {
  async beforeFetch({ url, options, cancel }) {
    const myToken = await getMyToken()

    if (!myToken)
      cancel()

    options.headers = {
      ...options.headers,
      Authorization: `Bearer ${myToken}`,
    }

    return {
      options,
    }
  },
})

`afterFetch`オプションを使用すると、レスポンスデータが更新される前にインターセプトできます。

TypeScript
const { data } = useFetch(url, {
  afterFetch(ctx) {
    if (ctx.data.title === 'HxH')
      ctx.data.title = 'Hunter x Hunter' // Modifies the response data

    return ctx
  },
})

`updateDataOnError`が`true`に設定されている場合、`onFetchError`オプションはレスポンスデータとエラーを更新される前にインターセプトできます。

TypeScript
const { data } = useFetch(url, {
  updateDataOnError: true,
  onFetchError(ctx) {
    // ctx.data can be null when 5xx response
    if (ctx.data === null)
      ctx.data = { title: 'Hunter x Hunter' } // Modifies the response data

    ctx.error = new Error('Custom Error') // Modifies the error
    return ctx
  },
})

console.log(data.value) // { title: 'Hunter x Hunter' }

リクエストメソッドと戻り値の型の設定

リクエストメソッドと戻り値の型は、適切なメソッドを`useFetch`の最後に追加することで設定できます。

TypeScript
// Request will be sent with GET method and data will be parsed as JSON
const { data } = useFetch(url).get().json()

// Request will be sent with POST method and data will be parsed as text
const { data } = useFetch(url).post().text()

// Or set the method using the options

// Request will be sent with GET method and data will be parsed as blob
const { data } = useFetch(url, { method: 'GET' }, { refetch: true }).blob()

カスタムインスタンスの作成

`createFetch`関数は、指定された事前設定されたオプションを持つuseFetch関数を返します。これは、同じベースURLを使用するか、承認ヘッダーを必要とするアプリケーション全体でAPIと対話する場合に役立ちます。

TypeScript
const useMyFetch = createFetch({
  baseUrl: 'https://my-api.com',
  options: {
    async beforeFetch({ options }) {
      const myToken = await getMyToken()
      options.headers.Authorization = `Bearer ${myToken}`

      return { options }
    },
  },
  fetchOptions: {
    mode: 'cors',
  },
})

const { isFetching, error, data } = useMyFetch('users')

事前設定されたインスタンスと新しく生成されたインスタンス間で`beforeFetch`、`afterFetch`、`onFetchError`の動作を制御したい場合、`combination`オプションを指定して`overwrite`または`chaining`を切り替えることができます。

TypeScript
const useMyFetch = createFetch({
  baseUrl: 'https://my-api.com',
  combination: 'overwrite',
  options: {
    // beforeFetch in pre-configured instance will only run when the newly spawned instance do not pass beforeFetch
    async beforeFetch({ options }) {
      const myToken = await getMyToken()
      options.headers.Authorization = `Bearer ${myToken}`

      return { options }
    },
  },
})

// use useMyFetch beforeFetch
const { isFetching, error, data } = useMyFetch('users')

// use custom beforeFetch
const { isFetching, error, data } = useMyFetch('users', {
  async beforeFetch({ url, options, cancel }) {
    const myToken = await getMyToken()

    if (!myToken)
      cancel()

    options.headers = {
      ...options.headers,
      Authorization: `Bearer ${myToken}`,
    }

    return {
      options,
    }
  },
})

イベント

onFetchResponse および onFetchError は、それぞれ fetch リクエストのレスポンスとエラー時に発火します。

TypeScript
const { onFetchResponse, onFetchError } = useFetch(url)

onFetchResponse((response) => {
  console.log(response.status)
})

onFetchError((error) => {
  console.error(error.message)
})

型宣言

型宣言を表示
typescript
export interface UseFetchReturn<T> {
  /**
   * Indicates if the fetch request has finished
   */
  isFinished: Readonly<Ref<boolean>>
  /**
   * The statusCode of the HTTP fetch response
   */
  statusCode: Ref<number | null>
  /**
   * The raw response of the fetch response
   */
  response: Ref<Response | null>
  /**
   * Any fetch errors that may have occurred
   */
  error: Ref<any>
  /**
   * The fetch response body on success, may either be JSON or text
   */
  data: Ref<T | null>
  /**
   * Indicates if the request is currently being fetched.
   */
  isFetching: Readonly<Ref<boolean>>
  /**
   * Indicates if the fetch request is able to be aborted
   */
  canAbort: ComputedRef<boolean>
  /**
   * Indicates if the fetch request was aborted
   */
  aborted: Ref<boolean>
  /**
   * Abort the fetch request
   */
  abort: Fn
  /**
   * Manually call the fetch
   * (default not throwing error)
   */
  execute: (throwOnFailed?: boolean) => Promise<any>
  /**
   * Fires after the fetch request has finished
   */
  onFetchResponse: EventHookOn<Response>
  /**
   * Fires after a fetch request error
   */
  onFetchError: EventHookOn
  /**
   * Fires after a fetch has completed
   */
  onFetchFinally: EventHookOn
  get: () => UseFetchReturn<T> & PromiseLike<UseFetchReturn<T>>
  post: (
    payload?: MaybeRefOrGetter<unknown>,
    type?: string,
  ) => UseFetchReturn<T> & PromiseLike<UseFetchReturn<T>>
  put: (
    payload?: MaybeRefOrGetter<unknown>,
    type?: string,
  ) => UseFetchReturn<T> & PromiseLike<UseFetchReturn<T>>
  delete: (
    payload?: MaybeRefOrGetter<unknown>,
    type?: string,
  ) => UseFetchReturn<T> & PromiseLike<UseFetchReturn<T>>
  patch: (
    payload?: MaybeRefOrGetter<unknown>,
    type?: string,
  ) => UseFetchReturn<T> & PromiseLike<UseFetchReturn<T>>
  head: (
    payload?: MaybeRefOrGetter<unknown>,
    type?: string,
  ) => UseFetchReturn<T> & PromiseLike<UseFetchReturn<T>>
  options: (
    payload?: MaybeRefOrGetter<unknown>,
    type?: string,
  ) => UseFetchReturn<T> & PromiseLike<UseFetchReturn<T>>
  json: <JSON = any>() => UseFetchReturn<JSON> &
    PromiseLike<UseFetchReturn<JSON>>
  text: () => UseFetchReturn<string> & PromiseLike<UseFetchReturn<string>>
  blob: () => UseFetchReturn<Blob> & PromiseLike<UseFetchReturn<Blob>>
  arrayBuffer: () => UseFetchReturn<ArrayBuffer> &
    PromiseLike<UseFetchReturn<ArrayBuffer>>
  formData: () => UseFetchReturn<FormData> &
    PromiseLike<UseFetchReturn<FormData>>
}
type Combination = "overwrite" | "chain"
export interface BeforeFetchContext {
  /**
   * The computed url of the current request
   */
  url: string
  /**
   * The request options of the current request
   */
  options: RequestInit
  /**
   * Cancels the current request
   */
  cancel: Fn
}
export interface AfterFetchContext<T = any> {
  response: Response
  data: T | null
}
export interface OnFetchErrorContext<T = any, E = any> {
  error: E
  data: T | null
}
export interface UseFetchOptions {
  /**
   * Fetch function
   */
  fetch?: typeof window.fetch
  /**
   * Will automatically run fetch when `useFetch` is used
   *
   * @default true
   */
  immediate?: boolean
  /**
   * Will automatically refetch when:
   * - the URL is changed if the URL is a ref
   * - the payload is changed if the payload is a ref
   *
   * @default false
   */
  refetch?: MaybeRefOrGetter<boolean>
  /**
   * Initial data before the request finished
   *
   * @default null
   */
  initialData?: any
  /**
   * Timeout for abort request after number of millisecond
   * `0` means use browser default
   *
   * @default 0
   */
  timeout?: number
  /**
   * Allow update the `data` ref when fetch error whenever provided, or mutated in the `onFetchError` callback
   *
   * @default false
   */
  updateDataOnError?: boolean
  /**
   * Will run immediately before the fetch request is dispatched
   */
  beforeFetch?: (
    ctx: BeforeFetchContext,
  ) =>
    | Promise<Partial<BeforeFetchContext> | void>
    | Partial<BeforeFetchContext>
    | void
  /**
   * Will run immediately after the fetch request is returned.
   * Runs after any 2xx response
   */
  afterFetch?: (
    ctx: AfterFetchContext,
  ) => Promise<Partial<AfterFetchContext>> | Partial<AfterFetchContext>
  /**
   * Will run immediately after the fetch request is returned.
   * Runs after any 4xx and 5xx response
   */
  onFetchError?: (ctx: {
    data: any
    response: Response | null
    error: any
  }) => Promise<Partial<OnFetchErrorContext>> | Partial<OnFetchErrorContext>
}
export interface CreateFetchOptions {
  /**
   * The base URL that will be prefixed to all urls unless urls are absolute
   */
  baseUrl?: MaybeRefOrGetter<string>
  /**
   * Determine the inherit behavior for beforeFetch, afterFetch, onFetchError
   * @default 'chain'
   */
  combination?: Combination
  /**
   * Default Options for the useFetch function
   */
  options?: UseFetchOptions
  /**
   * Options for the fetch request
   */
  fetchOptions?: RequestInit
}
export declare function createFetch(
  config?: CreateFetchOptions,
): typeof useFetch
export declare function useFetch<T>(
  url: MaybeRefOrGetter<string>,
): UseFetchReturn<T> & PromiseLike<UseFetchReturn<T>>
export declare function useFetch<T>(
  url: MaybeRefOrGetter<string>,
  useFetchOptions: UseFetchOptions,
): UseFetchReturn<T> & PromiseLike<UseFetchReturn<T>>
export declare function useFetch<T>(
  url: MaybeRefOrGetter<string>,
  options: RequestInit,
  useFetchOptions?: UseFetchOptions,
): UseFetchReturn<T> & PromiseLike<UseFetchReturn<T>>

ソースコード

ソースコードデモドキュメント

貢献者

Anthony Fu
wheat
Jelf
Ismail Gjevori
Anthony Fu
丶远方
qiang
KaKa
Toby Zerner
Jay214
webfansplz
Gergely Dremák
mrchar
陪我去看海吧
Pouya Mohammadkhani
BaboonKing
LJFloor
mymx2
Arthur Machado
Martijn Weghorst
KaKa
RAX7
Przemek Brzosko
abitwhy
sun0day
Young
sun0day
Curt Grimes
Yvan Zhu
ice
Antonio Román
Glandos
unknown_
btea
Shinigami
KaKa
Arda Soytürk

変更ログ

v12.0.0-beta.1 2024/11/21
0a9ed - feat!: Vue 2 サポートの削除、バンドルの最適化、クリーンアップ (#4349)
v11.3.0 2024/11/21
3d29c - feat: 配列ペイロードの 'json' 型の推論 (#4329)
3de68 - fix: スラッシュを1つにする (#4296)
v10.8.0 2024/2/20
f5587 - fix: 反復可能オブジェクト変換における不要なスプレッド演算子の削除 (#3660)
31d4a - fix: isFinishedisFetchingをリードオンリーとしてマーク (#3616)
a086e - fix: より厳格な型
v10.7.0 2023/12/5
fccf2 - feat: 依存関係のアップグレード (#3614)
8cbfd - fix: 読み込み時の 'Response' のクローン (#3607) (#3608)
3456d - fix: リクエスト完了後のステータスの即時変更 (#3603)
v10.6.0 2023/11/9
75ca2 - fix: リフレッシュによるリクエストの中断時に isFetching を false に設定しない (#3479)
v10.4.0 2023/8/25
945ca - feat: updateDataOnError オプションの導入 (#3092)
v10.3.0 2023/7/30
b7e3d - fix: 実行時の generated payloadType (#3251)
v10.1.1 2023/5/1
d051f - fix: combineCallbacks がオプションをマージしない (#3015)
v10.0.0-beta.4 2023/4/13
4d757 - feat(types)!: MaybeComputedRefMaybeRefOrGetter への名前変更
10e98 - feat(toRef)!: resolveReftoRef への名前変更
0a72b - feat(toValue): resolveUnreftoValue への名前変更
v10.0.0-beta.0 2023/3/14
78cfb - feat: 成功時のデータ更新 (#2711)
fff45 - fix: ステート更新前の中断 (#2805)
v9.13.0 2023/2/18
cd9d6 - feat: リフレッシュ時の以前のリクエストのキャンセル (#2750)
c2bc6 - fix: isFetchOptions のオブジェクトチェック
v9.9.0 2022/12/23
000fd - fix: formData ペイロードでの動作不良 (#2440)
v9.5.0 2022/11/9
934a8 - feat: baseURL に関係なく絶対 URL にカスタムリクエストを送信するサポート (#2210)
a8496 - feat: ライフサイクルハンドラの動作設定が可能に (#2333)
v9.3.1 2022年10月17日
45750 - 修正: `chainCallbacks` の動作を修正 (#2231)

MITライセンスの下でリリースされています。