Vue3 + 组合式 API + 完整可运行 的 3 个超级常用通用 Hooks:useRequest、useClipboard、useStorage
1. useRequest —— 统一管理接口请求最常用功能自动管理 data /loading/error支持手动 / 自动执行支持传参支持异步函数// src/hooks/useRequest.ts import { ref, onMounted } from vue export function useRequestT any( apiFn: (...args: any[]) PromiseT, options { immediate: true } ) { const data refT | null(null) const loading ref(false) const error refError | null(null) const run async (...args: any[]) { loading.value true error.value null try { const res await apiFn(...args) data.value res return res } catch (err) { error.value err as Error console.error(请求失败, err) } finally { loading.value false } } // 立即执行 if (options.immediate) { onMounted(() run()) } return { data, loading, error, run } }script setup langts import { useRequest } from /hooks/useRequest // 模拟接口 const getList () fetch(/api/list).then(res res.json()) const { data, loading, error, run } useRequest(getList) /script template div v-ifloading加载中.../div div v-else-iferror请求失败{{ error.message }}/div div v-else数据{{ data }}/div button clickrun刷新/button /template2. useClipboard —— 复制到剪贴板功能复制文本自动提示复制成功状态兼容所有现代浏览器// src/hooks/useClipboard.ts import { ref } from vue export function useClipboard() { const copied ref(false) const copy async (text: string) { try { await navigator.clipboard.writeText(text) copied.value true setTimeout(() (copied.value false), 1500) } catch (err) { console.error(复制失败, err) } } return { copy, copied } }script setup import { useClipboard } from /hooks/useClipboard const { copy, copied } useClipboard() /script template button clickcopy(我是要复制的内容) {{ copied ? 复制成功 : 点击复制 }} /button /template3. useStorage —— 本地存储localStorage /sessionStorage功能自动 JSON 序列化 / 反序列化响应式支持 localStorage /sessionStorage支持删除// src/hooks/useStorage.ts import { ref, watch } from vue type StorageType local | session export function useStorageT( key: string, defaultValue: T, type: StorageType local ) { const storage type local ? localStorage : sessionStorage // 初始化 const read () { try { const item storage.getItem(key) return item ? JSON.parse(item) : defaultValue } catch { return defaultValue } } const data refT(read()) // 监听变化自动保存 watch( data, (val) { storage.setItem(key, JSON.stringify(val)) }, { deep: true } ) // 删除 const remove () { storage.removeItem(key) data.value defaultValue } return { data, remove } }script setup import { useStorage } from /hooks/useStorage // 存 localStorage const { data: userInfo, remove } useStorage(userInfo, { name: 张三 }) // 存 sessionStorage // const { data } useStorage(token, , session) /script template div{{ userInfo.name }}/div button clickuserInfo.name 李四修改/button button clickremove删除/button /template// src/hooks/useModal.ts import { ref } from vue export function useModal(initVisible false) { const visible ref(initVisible) const open () (visible.value true) const close () (visible.value false) const toggle () (visible.value !visible.value) return { visible, open, close, toggle } }