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
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>)- 请求 URLoptions: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
}))
})
注意事项
- 缓存键: 确保为不同的请求使用唯一的缓存键
- 服务端预取: 只在需要 SEO 或首屏性能的场景下启用
- 错误处理: 始终提供错误处理逻辑
- 内存管理: 在 SPA 模式下注意清理不需要的缓存
示例
查看 src/components/DataFetch.vue 获取完整的使用示例。