Vue3 Hook:告别重复代码,打造更清爽的前端开发体验

更新日期: 2025-06-17阅读: 148标签: Hook

很多用 vue3 的开发者都遇到过这样的问题:多个组件里有几乎一样的逻辑代码。比如,好几个页面都要处理加载状态、都要调用同一个 api、都要做防抖处理。复制粘贴代码?后面改一个地方就要到处找,太麻烦!Vue3 提供的 组合式 API (Composition API) 和 自定义 Hook 就是来解决这个痛点的,它能让你把逻辑像乐高积木一样打包复用。


什么是 Vue3 Hook?

简单说,Vue3 Hook 就是一个 JavaScript 函数,它专门用来封装和复用 Vue 组件里的逻辑。这个函数内部可以自由使用 Vue3 的核心功能,比如 ref、reactive、computed、watch,甚至调用其他 Hook。

它为什么强大?

  1. 逻辑复用: 把组件里零散的功能(像数据获取、事件监听、状态管理)打包成一个函数,哪个组件需要就调用它。

  2. 代码清晰: 组件文件变小了,只关注模板和引入的逻辑块,容易看懂也容易维护。

  3. 功能解耦: 不同功能的逻辑放在不同的 Hook 里,互不干扰,修改一个不影响另一个。

手把手写一个实用 Hook:管理 Loading 状态

想象一下,很多页面在点击按钮调用 API 时都需要显示“加载中...”的提示。我们用 Hook 来搞定它。

// useLoading.js
import { ref } from 'vue';

export function useLoading(initialState = false) {
  // 创建一个响应式的 loading 状态,默认是传入的值(或 false)
  const isLoading = ref(initialState);

  // 启动 loading
  const startLoading = () => {
    isLoading.value = true;
  };

  // 结束 loading
  const stopLoading = () => {
    isLoading.value = false;
  };

  // 包裹一个异步任务,自动处理 loading 状态
  const withLoading = async (task) => {
    try {
      startLoading();
      const result = await task(); // 执行传入的异步函数
      return result;
    } finally { // 无论成功失败,都结束 loading
      stopLoading();
    }
  };

  // 把状态和方法都暴露给使用的组件
  return {
    isLoading,      // 当前是否正在加载 (响应式 ref)
    startLoading,   // 手动开始加载
    stopLoading,    // 手动结束加载
    withLoading     // 自动处理异步任务的加载状态
  };
}


在 Vue 组件中使用这个 Hook

现在,任何需要处理加载状态的组件,只需要几行代码:

<script setup>
import { useLoading } from './useLoading';

// 使用 Hook,获取它提供的方法和状态
const { isLoading, withLoading } = useLoading();

// 模拟一个异步请求,比如获取用户数据
const fetchUserData = () => {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve({ name: '张三', age: 30 }); // 模拟 API 返回数据
    }, 1500);
  });
};

// 按钮点击事件处理函数,用 withLoading 包裹异步请求
const handleClick = async () => {
  const userData = await withLoading(fetchUserData);
  console.log('获取到的用户数据:', userData);
};
</script>

<template>
  <div>
    <button @click="handleClick" :disabled="isLoading">
      {{ isLoading ? '加载中...' : '获取用户信息' }}
    </button>
  </div>
</template>

看看效果:

  1. 点击按钮,handleClick 被调用。

  2. withLoading(fetchUserData) 先启动 loading (isLoading 变成 true),按钮显示“加载中...”并禁用。

  3. 等待 fetchUserData 这个异步任务完成(模拟 1.5 秒)。

  4. 任务完成(或失败),finally 块保证 stopLoading 被调用,isLoading 变回 false,按钮恢复。

  5. 组件成功拿到用户数据。


还能封装哪些常用 Hook?

  • useFetch: 封装数据请求(GET/POST),自动处理 URL、参数、loading、错误。搜索关键词:Vue3 useFetch Hook 封装

  • useWindowResize: 监听浏览器窗口大小变化,实时更新组件。搜索关键词:Vue3 响应式窗口大小 Hook

  • useLocalStorage: 方便地读写浏览器 localStorage,数据是响应式的。搜索关键词:Vue3 localStorage 状态管理 Hook

  • useDebounce / useThrottle: 处理频繁触发的事件(如搜索框输入、滚动)。搜索关键词:Vue3 防抖节流 Hook 实现

  • useMousePosition: 跟踪鼠标在页面上的位置。搜索关键词:Vue3 鼠标坐标跟踪 Hook


为什么说 Vue3 Hook 开发效率高?

  1. 少写重复代码: 通用逻辑写一次,各处调用。

  2. 项目更好维护: 逻辑集中管理,修 bug 或加功能只改 Hook 文件。

  3. 组件更干净: 组件文件变小,只放跟当前页面紧密相关的内容。

  4. 团队协作更顺: 建立团队 Hook 库,新人快速上手,统一代码风格。


总结

Vue3 Hook(自定义组合式函数) 是提升开发效率和项目质量的重要工具。它解决了组件间逻辑复用难的痛点,让代码组织更清晰、更模块化。通过将通用功能(如加载状态、数据请求、事件监听)封装成独立的 Hook 函数,开发者可以像搭积木一样构建组件,显著减少重复代码。学习并应用 Vue3 Hook,是每一个想写出更简洁、更易维护 Vue 应用开发者的必备技能。开始尝试将你项目中的通用逻辑抽成 Hook,体验开发效率的提升吧!


链接: https://fly63.com/article/detial/12819

分享 10 个可以使用 Vue.js 制作的有用的自定义钩hook

Vue.js 是我使用的第一个 JavaScript 框架。 我可以说 Vue.js 是我进入 JavaScript 世界的第一扇门之一。 目前,Vue.js 仍然是一个很棒的框架。 我认为有了组合 API,Vue.js 只会增长得更多

pytest插件探索——hook开发

conftest.py可以作为最简单的本地plugin调用一些hook函数,以此来做些强化功能。pytest整个框架通过调用如下定义良好的hooks来实现配置,收集,执行和报告这些过程:

React中useState Hook 示例

到 React 16.8 目前为止,如果编写函数组件,然后遇到需要添加状态的情况,咱们就必须将组件转换为类组件。编写 class Thing extends React.Component,将函数体复制到render()方法中,修复缩进,最后添加需要的状态。

useContext Hook 是如何工作的?

所有这些新的React Hook之间都有一个宗旨:就是为了使函数组件像类组件一样强大。useContext hook 与其它几个有点不一样,但它在特定场景下还是很有用的。React 的 Context API 是一种在应用程序中深入传递数据的方法

结合React的Effect Hook分析组件副作用的清除

我们在DidMount的时候通过ID订阅了好友的在线状态,并且为了防止内存泄漏,我们需要在WillUnmount清除订阅,但是当组件已经显示在屏幕上时,friend prop 发生变化时会发生什么?

结合高阶函数聊聊useMemo和useCallback

useCallback和useMemo是其中的两个 hooks,本文旨在通过解决一个需求,结合高阶函数,深入理解useCallback和useMemo的用法和使用场景。 之所以会把这两个 hooks 放到一起说,是因为他们的主要作用都是性能优化

关于为什么使用React新特性Hook的一些实践与浅见

Hook是对函数式组件的一次增强,使得函数式组件可以做到class组件的state和生命周期。Hook的语法更加简练易懂,消除了class的生命周期方法导致的重复逻辑代码,解决了高阶组件难以理解和使用困难的问题。

React封装强业务hook的一个例子

最近因为使用列表展示的需求有点多,就想着把列表分页筛选的逻辑抽象一下。看了umi的一个useTable的hook,也不能满足业务需要,于是就自己写了一个,支持本地分页筛选和接口分页筛选。

React官方团队出手,补齐原生Hook短板

然而实际上,由于回调函数被useCallback缓存,形成闭包,所以点击的效果始终是sendMessage()。这就是「闭包陷阱」。以上代码的一种解决方式是「为useCallback增加依赖项」

实现一个自定义 React Hook:UseLocalStorageState

最近做需求,需要将数据保存到 localStorage 里,在组件初始化的时候获取,然后修改该值的时候,要保存到本地的 localStorage 中。很显然,这些逻辑完全可以封装为一个 React Hook

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!