表单统一校验或自定义校验
表单提交统一验证
useFormValidation.ts
import { ref } from "vue";
import { ElMessage } from "element-plus";
/**
* 表单验证规则类型
*/
export interface ValidationRule {
required?: boolean;
message: string;
validator?: (value: any) => boolean;
}
/**
* 表单验证 Composable
* 提供统一的表单验证逻辑
*/
export function useFormValidation<T extends Record<string, any>>(
rules: Record<keyof T, ValidationRule>
) {
const submitted = ref(false);
const errors = ref<Record<string, string>>({});
/**
* 检查字段是否无效
*/
const isInvalid = (fieldName: keyof T, value?: any): boolean => {
if (!submitted.value) return false;
const rule = rules[fieldName];
if (!rule) return false;
// 必填验证
if (rule.required && (!value || value === "")) {
return true;
}
// 自定义验证器
if (rule.validator && !rule.validator(value)) {
return true;
}
return false;
};
/**
* 验证单个字段
*/
const validateField = (fieldName: keyof T, value: any): boolean => {
const rule = rules[fieldName];
if (!rule) return true;
// 清除之前的错误
delete errors.value[fieldName as string];
// 必填验证
if (rule.required && (!value || value === "")) {
errors.value[fieldName as string] = rule.message;
return false;
}
// 自定义验证器
if (rule.validator && !rule.validator(value)) {
errors.value[fieldName as string] = rule.message;
return false;
}
return true;
};
/**
* 验证整个表单
*/
const validate = (data: T): boolean => {
submitted.value = true;
errors.value = {};
let isValid = true;
// 遍历所有规则进行验证
for (const [fieldName, rule] of Object.entries(rules)) {
const value = data[fieldName as keyof T];
if (!validateField(fieldName as keyof T, value)) {
isValid = false;
// 显示第一个错误消息
if (Object.keys(errors.value).length === 1) {
ElMessage.error(rule.message);
}
}
}
return isValid;
};
/**
* 验证必填字段(快速验证)
*/
const validateRequired = (data: T): boolean => {
submitted.value = true;
for (const [fieldName, rule] of Object.entries(rules)) {
if (rule.required) {
const value = data[fieldName as keyof T];
if (!value || value === "") {
ElMessage.error(rule.message);
return false;
}
}
}
return true;
};
/**
* 重置验证状态
*/
const resetValidation = () => {
submitted.value = false;
errors.value = {};
};
/**
* 获取字段错误消息
*/
const getFieldError = (fieldName: keyof T): string => {
return errors.value[fieldName as string] || "";
};
/**
* 检查是否有错误
*/
const hasErrors = (): boolean => {
return Object.keys(errors.value).length > 0;
};
return {
submitted,
errors,
isInvalid,
validateField,
validate,
validateRequired,
resetValidation,
getFieldError,
hasErrors,
};
}
/**
* 常用验证规则
*/
export const CommonValidationRules = {
required: (message: string): ValidationRule => ({
required: true,
message,
}),
url: (message: string = "请输入有效的URL"): ValidationRule => ({
message,
validator: (value: string) => {
if (!value) return true; // 非必填时允许空值
const urlPattern = /^https?:\/\/.+/;
return urlPattern.test(value);
},
}),
maxLength: (length: number, message?: string): ValidationRule => ({
message: message || `最多输入${length}个字符`,
validator: (value: string) => {
if (!value) return true;
return value.length <= length;
},
}),
minLength: (length: number, message?: string): ValidationRule => ({
message: message || `至少输入${length}个字符`,
validator: (value: string) => {
if (!value) return true;
return value.length >= length;
},
}),
};