表单验证完全指南

从基础到高级:构建可靠和用户友好的表单验证系统。

表单验证是确保数据质量和提升用户体验的关键环节。kinlink提供了强大而灵活的验证系统,支持从简单的格式检查到复杂的业务逻辑验证。本指南将带您全面掌握kinlink表单验证的各种技术和最佳实践。

验证系统概述

理解kinlink验证机制的工作原理

kinlink表单验证系统采用双重验证策略,确保数据的准确性和完整性:

验证类型说明

内置验证:基于表单配置中的字段类型和必填设置,自动执行基础验证 自定义验证:使用JavaScript API定义的高级验证规则,提供完全的控制权

本指南重点介绍自定义验证,它使您能够实现复杂的业务逻辑验证和个性化的用户体验。

自定义验证器管理

添加、配置和管理字段验证规则

自定义验证器是验证系统的核心,通过编写验证函数来实现各种验证需求。

基础验证器创建

验证器函数原理

验证器是一个接收字段值的函数,根据验证结果返回错误信息或undefined:

  • 验证失败:返回错误消息字符串
  • 验证通过:返回undefined
  • 空值处理:通常跳过对空值的验证

添加验证规则

使用addFieldValidator方法为字段添加自定义验证规则:

add-validator.js
// 为电子邮件字段添加自定义验证器
kinlink.formApi.addFieldValidator('email', (value) => {
// 如果字段为空则跳过验证
if (!value) return;

// 检查值是否为有效的电子邮件地址
if (!/^\w+([.-]?\w+)*@\w+([.-]?\w+)*(\.\w{2,3})+$/.test(value)) {
  return '请输入有效的电子邮件地址';
}

// 如果验证通过则返回undefined
return undefined;
});

表单初始化时配置验证

推荐在FORM_LOADED事件中集中配置所有验证规则:

form-loaded-validators.js
kinlink.events.on(kinlink.FormEvents.FORM_LOADED, () => {
const form = kinlink.formApi;

// 为各种字段添加验证器
form.addFieldValidator('email', validateEmail);
form.addFieldValidator('phone', validatePhone);
form.addFieldValidator('password', validatePassword);
});

// 验证器函数
function validateEmail(value) {
if (!value) return;
if (!/^\w+([.-]?\w+)*@\w+([.-]?\w+)*(\.\w{2,3})+$/.test(value)) {
  return '请输入有效的电子邮件地址';
}
return undefined;
}

function validatePhone(value) {
if (!value) return;
if (!/^\d{10}$/.test(value.replace(/\D/g, ''))) {
  return '请输入10位电话号码';
}
return undefined;
}

function validatePassword(value) {
if (!value) return;
if (value.length < 8) {
  return '密码长度必须至少为8个字符';
}
if (!/[A-Z]/.test(value)) {
  return '密码必须包含至少一个大写字母';
}
if (!/[a-z]/.test(value)) {
  return '密码必须包含至少一个小写字母';
}
if (!/\d/.test(value)) {
  return '密码必须包含至少一个数字';
}
return undefined;
}

验证器移除和管理

removeFieldValidator(fieldCode)

移除字段的自定义验证器,恢复到默认验证状态。

适用场景:动态验证规则切换、简化模式、条件性验证

remove-validator.js
// 从电子邮件字段移除验证器
kinlink.formApi.removeFieldValidator('email');

验证执行与检查

手动触发验证和获取验证结果

提供程序化的验证控制,支持实时验证和批量验证操作。

单字段验证

validateField(fieldCode, value)

手动验证指定字段的值,立即获取验证结果。

参数

  • fieldCode (string): 字段标识符
  • value (any): 待验证的值

返回值:错误信息字符串或undefined

适用场景:实时验证、条件验证、用户交互验证

validate-field.js
// 验证电子邮件字段
const error = kinlink.formApi.validateField('email', 'invalid-email');
console.log(error); // 输出: "请输入有效的电子邮件地址"

// 使用有效值验证
const noError = kinlink.formApi.validateField('email', '[email protected]');
console.log(noError); // 输出: undefined (验证通过)

全表单验证

validateForm()

验证表单中的所有字段,返回完整的验证结果报告。

返回值:包含验证状态和错误信息的对象

  • isValid (boolean): 整体验证是否通过
  • errors (object): 各字段的错误信息映射

适用场景:表单提交前检查、整体数据验证、错误汇总展示

validate-form.js
// 验证整个表单
const result = kinlink.formApi.validateForm();
console.log(result);
// 输出: {
//   errors: {
//     email: "请输入有效的电子邮件地址",
//     phone: "请输入10位电话号码"
//   },
//   isValid: false
// }

提交前验证集成

BEFORE_SUBMIT事件中集成验证,实现提交拦截和错误处理:

before-submit-validation.js
kinlink.events.on(kinlink.FormEvents.BEFORE_SUBMIT, (data) => {
const form = kinlink.formApi;

// 验证整个表单
const validationResult = form.validateForm();

if (!validationResult.isValid) {
  // 显示错误消息
  form.showError('提交前请修复验证错误。');
  
  // 阻止表单提交
  return false;
}

// 允许表单提交
return true;
});

错误信息管理

手动设置和清除字段错误状态

除了自动验证外,还支持手动管理错误信息,适用于服务端验证和业务逻辑检查。

单字段错误处理

setFieldError(fieldCode, errorMsg)

手动为字段设置错误信息,用于显示自定义错误或服务端返回的错误。

适用场景:服务端验证错误、业务逻辑错误、异步验证结果

clearFieldError(fieldCode)

清除字段的错误状态,恢复正常显示。

适用场景:错误修正后的状态重置、条件性错误清除

set-field-errors.js
// 为电子邮件字段设置错误消息
kinlink.formApi.setFieldError('email', '此电子邮件已被注册');

// 清除错误消息
kinlink.formApi.clearFieldError('email');

// 为多个字段设置错误消息
kinlink.formApi.setFieldsErrors({
email: '此电子邮件已被注册',
username: '此用户名已被使用'
});

常用验证模式库

可复用的验证规则和最佳实践

提供经过验证的常用验证模式,可直接应用于项目中。

基础数据验证

必填字段验证

确保重要字段不能为空,提供清晰的错误提示。

required-field.js
// 验证字段不为空
form.addFieldValidator('name', (value) => {
if (!value || value.trim() === '') {
  return '姓名为必填项';
}
return undefined;
});

邮箱格式验证

标准的邮箱地址格式检查,支持常见邮箱格式。

email-validation.js
// 验证电子邮件格式
form.addFieldValidator('email', (value) => {
if (!value) return;
if (!/^\w+([.-]?\w+)*@\w+([.-]?\w+)*(\.\w{2,3})+$/.test(value)) {
  return '请输入有效的电子邮件地址';
}
return undefined;
});

手机号码验证

灵活的电话号码验证,支持国际格式。

phone-validation.js
// 验证电话号码格式
form.addFieldValidator('phone', (value) => {
if (!value) return;
// 移除所有非数字字符
const phoneNumber = value.replace(/\D/g, '');
if (!/^\d{10,15}$/.test(phoneNumber)) {
  return '请输入有效的电话号码(10-15位数字)';
}
return undefined;
});

安全性验证

密码强度检查

多层次的密码安全性验证,确保密码符合安全要求。

password-strength.js
// 验证密码强度
form.addFieldValidator('password', (value) => {
if (!value) return;
if (value.length < 8) {
  return '密码长度必须至少为8个字符';
}
if (!/[A-Z]/.test(value)) {
  return '密码必须包含至少一个大写字母';
}
if (!/[a-z]/.test(value)) {
  return '密码必须包含至少一个小写字母';
}
if (!/\d/.test(value)) {
  return '密码必须包含至少一个数字';
}
if (!/[!@#$%^&*(),.?":{}|<>]/.test(value)) {
  return '密码必须包含至少一个特殊字符';
}
return undefined;
});

数值范围验证

数字范围检查

验证数值是否在合理范围内,支持年龄、金额等数值字段。

number-range.js
// 验证数字是否在指定范围内
form.addFieldValidator('age', (value) => {
if (value === null || value === undefined || value === '') return; // 允许空值,如果需要必填,单独添加规则
const age = Number(value);
if (isNaN(age)) {
  return '请输入有效的年龄';
}
if (age < 18 || age > 99) {
  return '年龄必须在18到99之间';
}
return undefined;
});

关联字段验证

字段匹配验证

验证两个字段内容是否一致,如密码确认等场景。

field-matching.js
// 验证两个字段是否匹配
form.addFieldValidator('confirmPassword', (value) => {
const password = form.getFieldValue('password');
if (value !== password) {
  return '密码不匹配';
}
return undefined;
});

// 当原始密码字段更改时,也触发确认密码字段的验证
form.events.on(kinlink.FormEvents.FIELD_CHANGE, (data) => {
if (data.fieldName === 'password') {
  form.validateField('confirmPassword', form.getFieldValue('confirmPassword'));
}
});

高级验证技术

异步验证和复杂业务逻辑处理

异步验证处理

由于kinlink验证器不直接支持Promise,异步验证需要通过事件和手动错误设置实现。

适用场景:用户名唯一性检查、服务端数据验证、第三方API验证

async-validation-example.js
// 示例:在字段更改时进行异步用户名可用性检查
let debounceTimer;
kinlink.events.on(kinlink.FormEvents.FIELD_CHANGE, (data) => {
if (data.fieldName === 'username') {
  clearTimeout(debounceTimer);
  debounceTimer = setTimeout(async () => {
    const username = data.value;
    if (!username) {
      kinlink.formApi.clearFieldError('username');
      return;
    }
    try {
      // 假设 checkUsernameAvailability 是一个返回Promise的函数
      // const isAvailable = await checkUsernameAvailability(username);
      // 模拟API调用
      const isAvailable = await new Promise(resolve => setTimeout(() => resolve(!['admin', 'test'].includes(username)), 500));
      
      if (!isAvailable) {
        kinlink.formApi.setFieldError('username', '此用户名已被使用');
      } else {
        kinlink.formApi.clearFieldError('username');
      }
    } catch (error) {
      kinlink.formApi.setFieldError('username', '检查用户名时出错');
      console.error('异步验证错误:', error);
    }
  }, 300); // 防抖处理
}
});

多重验证规则

验证器链式执行

单个字段可以添加多个验证器,按添加顺序依次执行,第一个失败的验证器将终止后续验证。

适用场景:分层验证逻辑、基础验证+业务验证的组合

multiple-validators.js
form.addFieldValidator('username', (value) => {
if (!value || value.trim() === '') {
  return '用户名为必填项';
}
return undefined;
});

form.addFieldValidator('username', (value) => {
if (!value) return; // 前一个验证器已经处理了空值情况
if (value.length < 3) {
  return '用户名长度至少为3个字符';
}
return undefined;
});

form.addFieldValidator('username', (value) => {
if (!value) return;
if (!/^[a-zA-Z0-9_]+$/.test(value)) {
  return '用户名只能包含字母、数字和下划线';
}
return undefined;
});

验证最佳实践

性能优化建议

  • 防抖处理:对异步验证使用防抖,避免频繁API调用
  • 验证时机:合理选择验证触发时机(实时 vs 失焦 vs 提交时)
  • 错误缓存:避免重复验证相同的值

用户体验优化

  • 渐进式验证:先进行基础验证,再进行复杂验证
  • 友好的错误信息:提供具体的错误描述和修改建议
  • 视觉反馈:结合样式变化提供验证状态反馈

可维护性建议

  • 验证器模块化:将验证函数独立定义,便于复用和测试
  • 配置驱动:使用配置对象管理验证规则
  • 错误信息集中管理:统一管理错误消息文本