【前端学习 + Vue + Hooks】什么是hooks?怎么使用hooks?
·
前言
博主没用过hooks,突然看大项目的时候,看到有个hooks文件夹,好奇什么是hooks,什么时候会用hooks,于是乎就有这篇文章了。
文章目录
一、为什么需要 Hook?
在 Vue3 中,Hook(钩子) 是基于 Composition API(组合式 API)封装的可复用逻辑函数,本质是将组件中分散的业务逻辑(如数据请求、表单验证、事件监听等)抽离成独立函数,实现逻辑复用和代码组织优化。
1.解决代码复用问题
Vue2 中通过 mixin 复用逻辑,但存在命名冲突、来源不清晰等问题;Hook 基于函数封装,逻辑独立且调用关系明确。
2.优化代码组织
将组件中相关的逻辑(如“分页加载”的请求、页码控制、加载状态)聚合到一个 Hook 中,避免代码碎片化。
3.增强类型支持:
结合 TypeScript 时,Hook 的类型推导更清晰,比 mixin 更易维护。
二、Hook 的核心特点
1.函数形式
通常以 useXxx 命名(如 usePagination、useForm),符合 React/Vue 社区的命名规范。
2. 依赖 Composition API
内部使用 ref、reactive、watch、onMounted 等 Vue3 API。
3. 可组合性
Hook 之间可以相互调用,实现复杂逻辑的拆分与组合。
三、项目中如何使用 Hook
以下通过 1个实际场景(表单验证)演示 Hook 的定义与使用。
(其实像之前写的 分享页面的方法,就可以单独抽离成一个hooks)
封装表单的“数据绑定、验证逻辑、提交状态”等通用逻辑。
1. 定义 Hook(src/hooks/useForm.ts)
import { ref, reactive, computed } from 'vue';
// 定义验证规则类型
type Rule = (value: any) => boolean | string; // 返回 true 表示验证通过,否则返回错误信息
type Rules<T> = { [K in keyof T]?: Rule | Rule[] }; // 每个字段的验证规则
export function useForm<T extends object>(
initialValues: T, // 表单初始值
rules: Rules<T> // 验证规则
) {
// 表单数据
const formData = reactive<T>({ ...initialValues });
// 错误信息
const errors = reactive<Partial<Record<keyof T, string>>>({});
// 提交状态
const submitting = ref(false);
// 单个字段验证
const validateField = (field: keyof T) => {
const value = formData[field];
const ruleList = Array.isArray(rules[field]) ? rules[field] : [rules[field]];
for (const rule of ruleList) {
if (!rule) continue;
const result = rule(value);
if (result !== true) {
errors[field] = result as string;
return false; // 验证失败
}
}
errors[field] = '';
return true; // 验证通过
};
// 整体表单验证
const validate = (): boolean => {
let isValid = true;
Object.keys(rules).forEach((field) => {
const result = validateField(field as keyof T);
if (!result) isValid = false;
});
return isValid;
};
// 提交表单
const submit = async (onSubmit: (data: T) => Promise<void>) => {
if (!validate()) return; // 验证失败则不提交
submitting.value = true;
try {
await onSubmit({ ...formData }); // 调用外部传入的提交逻辑
} finally {
submitting.value = false;
}
};
// 重置表单
const reset = () => {
Object.assign(formData, initialValues);
Object.keys(errors).forEach((field) => {
errors[field as keyof T] = '';
});
};
return {
formData,
errors,
submitting,
validateField,
validate,
submit,
reset
};
}
2. 在组件中使用 Hook(src/views/LoginForm.vue)
<template>
<form class="login-form">
<!-- 用户名输入 -->
<div class="form-item">
<label>用户名</label>
<input
v-model="formData.username"
@blur="validateField('username')"
placeholder="请输入用户名"
/>
<span class="error">{{ errors.username }}</span>
</div>
<!-- 密码输入 -->
<div class="form-item">
<label>密码</label>
<input
type="password"
v-model="formData.password"
@blur="validateField('password')"
placeholder="请输入密码"
/>
<span class="error">{{ errors.password }}</span>
</div>
<!-- 提交按钮 -->
<button
type="button"
@click="handleSubmit"
:disabled="submitting"
>
{{ submitting ? '提交中...' : '登录' }}
</button>
</form>
</template>
<script setup lang="ts">
import { useForm } from '@/hooks/useForm';
import { loginApi } from '@/api/user'; // 假设的登录接口
// 调用表单 Hook
const {
formData,
errors,
submitting,
validateField,
submit
} = useForm(
// 初始值
{ username: '', password: '' },
// 验证规则
{
username: [
(val) => val.trim() !== '' || '用户名不能为空',
(val) => val.length >= 3 || '用户名至少3个字符'
],
password: (val) => val.length >= 6 || '密码至少6个字符'
}
);
// 处理提交
const handleSubmit = () => {
submit(async (data) => {
// 调用登录接口
await loginApi(data);
alert('登录成功');
});
};
</script>
四、hooks参考
文档:快速通道


(以上的示例函数可以参考)
总结
- Hook 的本质:用函数封装可复用逻辑,依赖 Vue3 的 Composition API。
- 使用步骤:
- 定义:创建
useXxx.ts文件,内部实现逻辑并返回需要暴露的状态和方法。- 调用:在组件中导入 Hook 并执行,解构出需要的状态和方法,直接在模板或逻辑中使用。
- 优势:逻辑复用更清晰、代码组织更有序、类型支持更友好,是 Vue3 项目中推荐的逻辑复用方案。
通过 Hook,可将项目中重复出现的逻辑(如分页、表单、权限、订阅等)抽离,大幅提升代码复用率和可维护性。
更多推荐



所有评论(0)