Vue Form Validator
🚀 Vue 3 表单验证组合式 API,提供类似 Ant Design Vue Form 的强大表单验证功能
[npm 仓库](www.npmjs.com/package/@ea…)
✨ 特性
- 🎯 Vue 3 优化: 基于 Composition API 构建,完全支持响应式
- 🔧 TypeScript 支持: 完整的类型定义,享受类型安全和智能提示
- 🌊 灵活验证: 支持单字段、多字段、整表单验证
- 🏗️ 深度规则: 支持嵌套对象和数组的复杂验证场景
- ⚡ 防抖优化: 可配置的防抖验证,提升用户体验
- 🧪 开发工具: 内置性能监控和规则验证工具
- 📦 轻量无依赖: 基于 async-validator,体积小巧
- 🔄 兼容 Element Plus: 无缝集成
el-form-item组件
解决 Element Plus 表单验证的痛点
Element Plus 的表单验证虽然功能完善,但在现代 Vue 3 开发中存在一些局限性:
🔗 组件耦合度高
<!-- Element Plus 方式:必须依赖 el-form 和 el-form-item -->
<el-form :model="form" :rules="rules" ref="formRef">
<el-form-item label="用户名" prop="username">
<el-input v-model="form.username" />
</el-form-item>
</el-form>
<!-- Vue Form Validator:解耦组件依赖 -->
<el-form-item label="用户名" v-bind="validationState.username">
<el-input v-model="model.username" />
</el-form-item>
📱 Composition API 支持有限
// Element Plus:需要通过 ref 获取表单实例
const formRef = ref()
const validate = () => formRef.value.validate()
// Vue Form Validator:纯 Composition API 体验
const { validate } = useForm(model, rules)
await validate() // 直接调用
🌊 深度验证困难
// Element Plus:嵌套验证配置复杂
const rules = {
'user.profile.name': [{ required: true }], // 不够直观
}
// Vue Form Validator:原生深度验证支持
const rules = {
'user.profile': {
type: 'object',
fields: {
name: { required: true, message: '请输入姓名' },
contacts: {
type: 'array',
defaultField: {
/* 数组元素验证规则 */
},
},
},
},
}
🚀 Vue Form Validator 的技术优势
1. 智能响应式验证状态
// 验证状态自动响应式更新,无需手动管理
interface UseFormValidateInfo {
required?: boolean // 自动检测是否必填
validateStatus?: 'error' | 'validating' | 'success' | ''
error?: string // 错误信息
}
2. 高性能懒加载机制
- 使用 Proxy 实现深度字段的懒加载
- 只有在访问时才创建对应的验证规则和监听器
- 智能内存管理,自动清理不需要的资源
3. 内置防抖优化
const { validationState } = useForm(model, rules, {
debounceMs: 300, // 用户停止输入 300ms 后才验证
})
4. 完整的 TypeScript 支持
interface UserForm {
username: string
email: string
}
// 完整的类型推导和约束
const { validationState } = useForm<UserForm>(model, rules)
// validationState.username ✅ 类型安全
// validationState.nonexistent ❌ TypeScript 错误
📊 性能对比
| 特性 | Vue Form Validator | Element Plus Form |
|---|---|---|
| 响应式更新 | 🟢 精确更新,只更新变化的字段 | 🟡 可能触发整个表单重新渲染 |
| 内存使用 | 🟢 懒加载 + 自动清理 | 🟡 需要手动管理 |
| 验证频率 | 🟢 内置防抖,可配置 | 🟡 需要手动实现 |
| 深度验证 | 🟢 原生支持,性能优化 | 🔴 复杂场景性能差 |
| TypeScript | 🟢 完整类型推导 | 🟡 基础类型支持 |
| 组合式 API | 🟢 专为 Composition API 设计 | 🟡 混合支持 |
📦 安装
# npm
npm install @easily-js/vue-form-validator async-validator
# yarn
yarn add @easily-js/vue-form-validator async-validator
# pnpm
pnpm add @easily-js/vue-form-validator async-validator
🚀 快速开始
基础用法
<template>
<el-form-item label="用户名" v-bind="validationState.username">
<el-input v-model="model.username" placeholder="请输入用户名" />
</el-form-item>
<el-form-item label="邮箱" v-bind="validationState.email">
<el-input v-model="model.email" placeholder="请输入邮箱" />
</el-form-item>
<el-form-item label="年龄" v-bind="validationState.age">
<el-input-number v-model="model.age" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleSubmit">提交</el-button>
<el-button @click="resetFields">重置</el-button>
<el-button @click="clearValidate">清除验证</el-button>
</el-form-item>
</template>
<script setup lang="ts">
import { reactive } from 'vue'
import { useForm, type UseFormRules } from 'vue-form-validator'
// 定义表单数据类型
interface UserForm {
username: string
email: string
age: number
}
// 定义验证规则
const rules: UseFormRules<UserForm> = {
username: [
{ required: true, message: '请输入用户名' },
{ min: 3, max: 20, message: '用户名长度为 3-20 个字符' },
],
email: [
{ required: true, message: '请输入邮箱地址' },
{ type: 'email', message: '请输入正确的邮箱格式' },
],
age: [
{ required: true, message: '请输入年龄' },
{ type: 'number', min: 18, max: 120, message: '年龄必须在 18-120 之间' },
],
}
// 初始化表单
const model = reactive<UserForm>({
username: '',
email: '',
age: 18,
})
// 使用 useForm
const { validationState, validate, validateField, resetFields, clearValidate } =
useForm(model, rules)
// 提交处理
async function handleSubmit() {
try {
await validate()
console.log('表单验证通过', model)
// 处理提交逻辑
} catch (errorInfo) {
console.log('验证失败', errorInfo)
}
}
</script>
高级用法
1. 防抖验证
<script setup lang="ts">
// 配置 300ms 防抖延迟
const { validationState, validate } = useForm(model, rules, {
debounceMs: 300, // 用户停止输入 300ms 后再触发验证
})
</script>
2. 深度规则验证
<script setup lang="ts">
import { reactive } from 'vue'
// 嵌套对象表单
const model = reactive({
user: {
profile: {
name: '',
contact: {
email: '',
phone: '',
},
},
preferences: {
theme: 'light',
notifications: true,
},
},
})
// 深度规则
const rules = {
'user.profile.name': [{ required: true, message: '请输入姓名' }],
'user.profile.contact.email': [
{ required: true, message: '请输入邮箱' },
{ type: 'email', message: '邮箱格式不正确' },
],
'user.profile.contact.phone': [
{ required: true, message: '请输入手机号' },
{ pattern: /^1[3-9]\d{9}$/, message: '手机号格式不正确' },
],
}
const { validationState } = useForm(model, rules, {
deepRule: true, // 启用深度规则
})
</script>
<template>
<!-- 访问嵌套字段的验证状态 -->
<el-form-item label="姓名" v-bind="validationState['user.profile.name']">
<el-input v-model="model.user.profile.name" />
</el-form-item>
<el-form-item
label="邮箱"
v-bind="validationState['user.profile.contact.email']"
>
<el-input v-model="model.user.profile.contact.email" />
</el-form-item>
</template>
3. 数组验证
<script setup lang="ts">
const model = reactive({
tags: [''],
users: [{ name: '', email: '' }],
})
const rules = {
tags: {
type: 'array',
required: true,
defaultField: { type: 'string', required: true, message: '标签不能为空' },
},
users: {
type: 'array',
required: true,
defaultField: {
type: 'object',
fields: {
name: { required: true, message: '请输入姓名' },
email: { type: 'email', required: true, message: '请输入正确的邮箱' },
},
},
},
}
</script>
4. 自定义验证器
<script setup lang="ts">
// 异步验证器示例
const checkUsernameAvailability = async (rule: any, value: string) => {
if (!value) return Promise.reject('请输入用户名')
// 模拟 API 调用
const response = await fetch(`/api/check-username?name=${value}`)
const { available } = await response.json()
if (!available) {
return Promise.reject('用户名已被占用')
}
}
const rules = {
username: [
{ required: true, message: '请输入用户名' },
{ validator: checkUsernameAvailability, trigger: 'blur' },
],
}
</script>