useLazyApiFetch

View source
Lazy variant of useApiFetch that does not block client-side navigation — the page renders immediately.

Usage

Use the auto-imported useLazyApiFetch composable for API requests. Equivalent to useApiFetch(url, { ...options, lazy: true }). In lazy mode the request does not block client-side navigation; the page renders immediately and data loads in the background.

<script setup lang="ts">
interface User {
  id: number
  name: string
  email: string
}

// Lazy-load user data
const { data, status } = useLazyApiFetch<User[]>('/users')
</script>

<template>
  <div>
    <div v-if="status === 'pending'">
      Loading...
    </div>
    <div v-else-if="status === 'error'">
      Failed to load
    </div>
    <div v-else-if="data">
      <div v-for="user in data" :key="user.id">
        {{ user.name }}
      </div>
    </div>
  </div>
</template>
  • useLazyApiFetch does not block client-side navigation, making it suitable for non-critical data (user lists, comments, etc.).
  • During client-side navigation data is initially null and status is 'pending'; you must handle the loading state.
  • Inherits all features of useApiFetch (auth, Toast, business status code checking, etc.).
For data that is required on first render, use useApiFetch (non-lazy mode) to block navigation and ensure data is ready.
See the useApiFetch documentation for full API options and feature descriptions

Example

The page renders first, then enters the pending state. data is null until the response arrives; pair with pending / status to handle the loading state:

ready

lazy 模式:页面先渲染再进入 pending;data 在拿到响应前为 null

{
  "id": "me",
  "name": "Movk Demo",
  "email": "demo@movk.dev",
  "avatar": "/avatar.png",
  "role": "developer",
  "issuedAt": "2026-06-29T20:55:14.535Z"
}
<script setup lang="ts">
interface Profile {
  id: string
  name: string
  email: string
}

const { data, pending, error, refresh } = useLazyApiFetch<Profile>('/profile')
</script>

<template>
  <div class="flex flex-col gap-3">
    <div class="flex items-center gap-2 flex-wrap">
      <UBadge v-if="pending" color="warning" variant="subtle">
        pending
      </UBadge>
      <UBadge v-else-if="error" color="error" variant="subtle">
        error
      </UBadge>
      <UBadge v-else color="success" variant="subtle">
        ready
      </UBadge>
      <UButton size="sm" variant="outline" icon="i-lucide-refresh-cw" @click="refresh()">
        刷新
      </UButton>
    </div>
    <p class="text-xs text-muted">
      lazy 模式:页面先渲染再进入 pending;data 在拿到响应前为 null
    </p>
    <pre class="text-xs p-3 rounded bg-elevated overflow-auto">{{ error ? { error: error.message } : data }}</pre>
  </div>
</template>

API

useLazyApiFetch()

useLazyApiFetch<T = unknown, DataT = T>(url: string | (() => string), options?: UseApiFetchOptions<T, DataT>): UseApiFetchReturn<DataT>

Creates a lazy API request.

Parameters

url
string | (() => string) required
Request URL or a function returning the URL. Supports reactive URLs.
options
UseApiFetchOptions<T, DataT>
Request configuration options. Supports all options of useApiFetch.
The lazy option is forced to true; no need to specify it manually.

Type Parameters

T
type
Business data type (already automatically unwrapped by $api).
DataT
type
The final type after transform conversion. Defaults to T.

Returns

Same return value as useApiFetch.

Changelog

No recent changes
Copyright © 2025 - 2026 YiXuan - MIT License