Vue 3 组合式 API:自定义 Hook 与逻辑复用

1. 什么是自定义 Hook?

自定义 Hook 是 Vue 3 组合式 API 的核心实践之一,本质是一个返回响应式数据或方法的 JavaScript 函数。通过封装通用逻辑(如数据获取、状态管理、事件监听),实现跨组件复用,避免代码重复。

2. 创建自定义 Hook 的步骤
// 示例:鼠标位置跟踪 Hook
import { ref, onMounted, onUnmounted } from 'vue'

export function useMousePosition() {
  const x = ref(0)
  const y = ref(0)
  
  const updatePosition = (e) => {
    x.value = e.clientX
    y.value = e.clientY
  }

  onMounted(() => window.addEventListener('mousemove', updatePosition))
  onUnmounted(() => window.removeEventListener('mousemove', updatePosition))

  return { x, y } // 返回响应式对象
}

3. 在组件中使用 Hook
<template>
  <div>鼠标坐标:($$x$$, $$y$$)</div>
</template>

<script setup>
import { useMousePosition } from './useMousePosition'

const { x, y } = useMousePosition() // 直接解构使用
</script>

4. 核心优势
  • 逻辑解耦:将业务逻辑与 UI 组件分离
  • 复用性:同一 Hook 可跨多个组件复用
  • 可测试性:独立测试 Hook 逻辑,无需渲染组件
  • 组合能力:多个 Hook 可嵌套组合(如 useFetch + usePagination
5. 设计最佳实践
  1. 命名规范:以 use 开头(如 useDarkMode
  2. 单一职责:每个 Hook 只解决一个特定问题
  3. 返回响应式对象:确保解构后仍保持响应性
  4. 清理副作用:在 onUnmounted 中回收资源(定时器、事件监听)
6. 复杂场景示例:数据请求 Hook
import { ref } from 'vue'

export function useFetch(url) {
  const data = ref(null)
  const error = ref(null)
  const loading = ref(false)

  const fetchData = async () => {
    try {
      loading.value = true
      const res = await fetch(url)
      data.value = await res.json()
    } catch (err) {
      error.value = err
    } finally {
      loading.value = false
    }
  }

  fetchData() // 自动执行

  return { data, error, loading, retry: fetchData }
}

7. 与传统选项式 API 对比
特性 选项式 API 组合式 API + Hook
逻辑组织 按选项分散 按功能聚合
复用方式 Mixins/高阶组件 函数调用
代码可读性 跳转查看 线性阅读
TypeScript 支持 较弱 原生友好
8. 常见应用场景
  • 表单处理(useForm
  • 定时器管理(useInterval
  • 浏览器存储(useLocalStorage
  • 手势识别(useSwipe

关键原则:当发现多个组件包含相似代码时,即可抽象为自定义 Hook。Vue 官方库 VueUse 提供了 200+ 现成 Hook 实现参考。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐