vue3的hooks库,和自定义hooks
在 Vue 3 的 Composition API 时代,"Hooks"(即自定义组合函数,Custom Composables)已经成为组织和复用逻辑的核心方式,类似于 React 的自定义 Hook。社区也涌现了许多优秀的 Vue 3 Hooks 库,极大提升了开发效率。
简单说就是:Vue 3 的 Hooks 让代码复用变得特别简单,不用像 Vue 2 那样用 mixins 那么麻烦。
✅ 一、推荐的 Vue 3 Hooks 库(第三方)
以下是目前最流行、维护良好、功能丰富的 Vue 3 Hooks 库:
1. VueUse 🔥(强烈推荐)
🌟 Vue 3 生态中最强大、最全面的 Composables 库,由 Anthony Fu(Vue 官方团队成员) 维护。
✅ 特点:
- 超过 200+ 个高质量
composables- 基本啥都有 - 支持 Vue 3 和 Nuxt 3 - 兼容性好
- 类型推导完美(TypeScript 友好) - 写代码有提示
- 按需引入,Tree-shakable - 打包体积小
- 支持浏览器 API 封装:
useMouse,useDark,useStorage,useBreakpoints,useFetch等 - 常用功能都封装好了
常用 API 示例:
import { useMouse, useLocalStorage, useDark, useFullscreen } from '@vueuse/core'
const { x, y } = useMouse()
const token = useLocalStorage('token', '')
const isDark = useDark()
const { isFullscreen, enterFullscreen, exitFullscreen } = useFullscreen()
安装:
npm install @vueuse/core
👉 官网:https://vueuse.org
2. oh-vue-icons(配套图标库,非 hooks,但常搭配使用)
虽不是 hooks 库,但由同一位作者开发,常与 VueUse 搭配使用。
3. 其他可选库(按需了解)
| 库名 | 说明 |
|---|---|
vue-composable | 早期的 Composables 库,功能较少,VueUse 出现后逐渐被替代 |
@vueuse/router | VueUse 的扩展,封装了 Vue Router 相关逻辑(如 useRouteParams) |
@vueuse/head | SEO 标题/元信息管理(类似 vue-meta) |
💡 推荐只使用 VueUse 即可满足 90% 以上需求。 - 一个库就够了,不用装太多
✅ 二、如何编写自己的 Custom Hooks(自定义 Composables)
你可以将常用逻辑封装成自己的 useXxx 函数,放在 composables/ 目录下。
说白了就是:把常用的逻辑抽出来,下次直接用,不用重复写。
示例 1:useLocalStorage(带响应式 + 监听外部变化) - 这个最常用
// composables/useLocalStorage.js
import { ref, watch, onMounted, onUnmounted } from 'vue'
export function useLocalStorage(key, defaultValue = '') {
const value = ref(JSON.parse(localStorage.getItem(key) || 'null') ?? defaultValue)
// 同步到 localStorage
watch(value, (val) => {
localStorage.setItem(key, JSON.stringify(val))
}, { deep: true })
// 监听其他标签页的 localStorage 变化
const handler = (e) => {
if (e.key === key) {
const newVal = e.newValue ? JSON.parse(e.newValue) : defaultValue
value.value = newVal
}
}
onMounted(() => {
window.addEventListener('storage', handler)
})
onUnmounted(() => {
window.removeEventListener('storage', handler)
})
return {
value,
setValue: (newValue) => {
value.value = newValue
}
}
}
使用:
import { useLocalStorage } from '@/composables/useLocalStorage'
const { value: username, setValue } = useLocalStorage('username', 'guest')
示例 2:useApiFetch(封装请求 + loading + error) - 接口请求必备
// composables/useApiFetch.js
import { ref } from 'vue'
import axios from 'axios'
export function useApiFetch(url) {
const data = ref(null)
const loading = ref(true)
const error = ref(null)
async function fetch() {
loading.value = true
error.value = null
try {
const res = await axios.get(url)
data.value = res.data
} catch (err) {
error.value = err.message
} finally {
loading.value = false
}
}
// 自动请求
fetch()
return { data, loading, error, refetch: fetch }
}
使用:
const { data, loading, error } = useApiFetch('/api/user')
示例 3:useForm(表单管理) - 表单验证神器
// composables/useForm.js
import { ref, computed } from 'vue'
export function useForm(initialData) {
const form = ref({ ...initialData })
const errors = ref({})
const hasError = computed(() => Object.keys(errors.value).length > 0)
function setField(key, value) {
form.value[key] = value
delete errors.value[key]
}
function validate(rules) {
let valid = true
for (const [key, rule] of Object.entries(rules)) {
if (rule.required && !form.value[key]) {
errors.value[key] = rule.message || '必填'
valid = false
}
}
return valid
}
return {
form,
errors,
hasError,
setField,
validate
}
}
✅ 三、最佳实践建议
| 实践 | 建议 |
|---|---|
| ✅ 命名规范 | 以 use 开头,如 useModal, useAuth, useDrag - 大家都这么写 |
| ✅ 目录结构 | 创建 composables/ 目录统一管理 - 别乱放 |
| ✅ 返回响应式数据 | 使用 ref, reactive, computed - 这样才能响应式 |
| ✅ 清理副作用 | onMounted, onUnmounted 中处理事件监听、定时器等 - 内存泄漏要避免 |
| ✅ 支持参数和默认值 | 提高复用性 - 灵活一点 |
| ✅ 类型提示 | 使用 TypeScript 更佳 - 有提示写代码快 |
✅ 四、VueUse 常用 Hooks 分类推荐
| 类别 | 推荐 API |
|---|---|
| 状态 | useStorage, useSessionStorage, usePreferredDark - 本地存储相关 |
| DOM | useMouse, useScroll, useElementSize, useIntersectionObserver - 鼠标滚动等 |
| 设备 | useBreakpoints, useDeviceOrientation, useGeolocation - 设备信息 |
| 网络 | useFetch, useOnline, useWebSocket - 网络请求 |
| 动画 | useTimeout, useInterval, useTransition - 定时器和动画 |
| 媒体 | useMediaControls, useAudio, useVideo - 音视频控制 |
| 路由 | useRoute, useRouter, useRouteParams(来自 @vueuse/router) - 路由相关 |
✅ 总结
| 内容 | 推荐 |
|---|---|
| 🔝 最佳 Hooks 库 | ✅ VueUse - 官方推荐 |
| 🔧 自定义 Hooks | ✅ 封装 useXxx 到 composables/ 目录 - 统一管理 |
| 🧩 常见封装 | useLocalStorage, useFetch, useForm, useModal - 这些最常用 |
| 🛠️ 开发建议 | 使用 TypeScript + 解构返回 + 清理副作用 - 代码质量高 |
💬 一句话总结:
Vue 3 的composables+VueUse= 开发效率飞升,逻辑复用从未如此简单!
简单说就是:有了 VueUse,写代码就像搭积木一样简单,不用重复造轮子。