You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

3.8 KiB

useFetch SSR Hook

这是一个专为 Vue 3 SSR 应用设计的 useFetch hook,支持服务端预取和客户端水合。

特性

  • SSR 兼容: 支持服务端预取和客户端水合
  • 数据缓存: 避免重复请求,提升性能
  • 错误处理: 完整的错误处理机制
  • 加载状态: 内置 loading 状态管理
  • TypeScript: 完整的类型支持
  • 灵活配置: 支持自定义缓存键、转换函数等

基本用法

import { useFetch } from './compose/useFetch'

// 基本用法
const { data, error, pending, refresh } = useFetch('/api/users')

// 带配置的用法
const { data, error, pending, refresh } = useFetch(
  'https://api.example.com/users/1',
  {
    key: 'user-1',           // 缓存键
    server: true,            // 启用服务端预取
    transform: (data) => ({   // 数据转换
      id: data.id,
      name: data.name
    }),
    onError: (err) => {      // 错误处理
      console.error(err)
    }
  }
)

API 参考

useFetch(url, options?)

参数

  • url: string | (() => string) | (() => Promise<string>) - 请求 URL
  • options: UseFetchOptions - 配置选项

返回值

  • data: Ref<T | null> - 响应数据
  • error: Ref<Error | null> - 错误信息
  • pending: Ref<boolean> - 加载状态
  • refresh(): () => Promise<void> - 刷新数据
  • execute(): () => Promise<void> - 手动执行请求

UseFetchOptions

interface UseFetchOptions {
  key?: string                    // 缓存键
  server?: boolean               // 是否启用服务端预取
  default?: () => any            // 默认值
  transform?: (data: any) => any  // 数据转换函数
  onError?: (error: Error) => void // 错误处理函数
}

SSR 集成

服务端设置

entry-server.ts 中:

import { createSSRContext } from './compose/useFetch'

export async function render(url: string) {
  const { app } = createApp()
  
  // 创建 SSR 上下文
  const ssrContext = createSSRContext()
  app.config.globalProperties.$ssrContext = ssrContext
  
  const html = await renderToString(app)
  
  // 将数据序列化到 HTML
  const ssrData = JSON.stringify(Array.from(ssrContext.cache?.entries() || []))
  const head = `
    <script>
      window.__SSR_CONTEXT__ = {
        cache: new Map(${ssrData})
      };
    </script>
  `
  
  return { html, head }
}

客户端设置

entry-client.ts 中:

import { hydrateSSRContext, clearSSRContext } from './compose/useFetch'

// 水合 SSR 数据
if (typeof window !== 'undefined' && window.__SSR_CONTEXT__) {
  hydrateSSRContext(window.__SSR_CONTEXT__)
}

app.mount('#app')

// 水合完成后清理
clearSSRContext()

高级用法

动态 URL

const userId = ref(1)
const { data } = useFetch(() => `/api/users/${userId.value}`)

条件请求

const shouldFetch = ref(false)
const { data } = useFetch(
  () => shouldFetch.value ? '/api/data' : null,
  { server: false } // 禁用服务端预取
)

错误处理

const { data, error, pending } = useFetch('/api/data', {
  onError: (err) => {
    // 自定义错误处理
    console.error('请求失败:', err)
    // 可以显示用户友好的错误消息
  }
})

数据转换

const { data } = useFetch('/api/users', {
  transform: (users) => users.map(user => ({
    id: user.id,
    name: user.name,
    email: user.email
  }))
})

注意事项

  1. 缓存键: 确保为不同的请求使用唯一的缓存键
  2. 服务端预取: 只在需要 SEO 或首屏性能的场景下启用
  3. 错误处理: 始终提供错误处理逻辑
  4. 内存管理: 在 SPA 模式下注意清理不需要的缓存

示例

查看 src/components/DataFetch.vue 获取完整的使用示例。