Vue—— Vue 3 + Element Plus 表单输入校验和自动格式化工具函数详解
Vue | July 11, 2026
文章链接:https://blog.csdn.net/qq_43201350/article/details/156505250
在前端开发中,表单输入校验和格式化是一个常见但繁琐的任务。本文介绍一套完整的表单输入校验和自动格式化工具函数,帮助开发者提升用户体验并减少重复代码。
技术难点
-
如何自动为表单元素添加合适的属性(如最大长度、占位符等)
-
实现通用的数据校验机制,支持多种数据类型
-
动态监听 DOM 变化,为新添加的元素自动应用规则
-
实时显示校验错误信息并高亮错误字段
实现效果
-
自动为不同类型的输入框添加默认属性
-
实时校验用户输入并给出友好提示
-
支持自定义校验规则
-
无需手动为每个表单元素添加校验逻辑
示例演示
下面是一套完整的表单输入校验和格式化工具函数:
// 表单校验规则定义
const validationRules = {
// 手机号码校验
phone: {
pattern: /^1[3-9]\d{9}$/,
message: '请输入正确的手机号码'
},
// 邮箱校验
email: {
pattern: /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/,
message: '请输入正确的邮箱地址'
},
// 用户名校验(4-16位字母、数字、下划线)
username: {
pattern: /^[a-zA-Z0-9_]{4,16}$/,
message: '用户名必须是4-16位字母、数字或下划线'
}
};
/**
* 为输入元素设置默认属性
* @param {HTMLElement} element - 表单元素
*/
function setInputDefaults(element) {
const tagName = element.tagName.toLowerCase();
const type = element.type;
// 已经处理过的元素跳过
if (element._processed) return;
if (tagName === 'input') {
// 为文本输入框添加默认最大长度和占位符
if (type === 'text' && !element.hasAttribute('maxlength')) {
element.setAttribute('maxlength', '100');
if (!element.hasAttribute('placeholder')) {
element.setAttribute('placeholder', '请输入内容');
}
}
// 为数字输入框添加最大值限制
if (type === 'number' && !element.hasAttribute('max')) {
element.setAttribute('max', '999999999');
}
}
if (tagName === 'textarea' && !element.hasAttribute('maxlength')) {
element.setAttribute('maxlength', '500');
element.setAttribute('rows', '4');
if (!element.hasAttribute('placeholder')) {
element.setAttribute('placeholder', '请输入内容');
}
}
// 标记为已处理
element._processed = true;
}
/**
* 显示校验错误信息
* @param {HTMLElement} element - 表单元素
* @param {string} message - 错误信息
*/
function showValidationError(element, message) {
// 移除已有错误提示
removeValidationError(element);
// 创建错误提示元素
const errorDiv = document.createElement('div');
errorDiv.className = 'validation-error';
errorDiv.textContent = message;
errorDiv.style.cssText = `
color: #ff4d4f;
font-size: 12px;
margin-top: 4px;
`;
// 高亮错误字段
element.style.borderColor = '#ff4d4f';
// 插入错误提示
element.parentNode.appendChild(errorDiv);
element._errorElement = errorDiv;
}
/**
* 移除校验错误信息
* @param {HTMLElement} element - 表单元素
*/
function removeValidationError(element) {
if (element._errorElement) {
element._errorElement.remove();
element._errorElement = null;
element.style.borderColor = '';
}
}
/**
* 添加输入校验功能
* @param {HTMLElement} element - 表单元素
*/
function addInputValidation(element) {
const dataType = element.getAttribute('data-type');
if (!dataType || !validationRules[dataType]) return;
// 创建校验处理函数
const validationHandler = (event) => {
const value = event.target.value.trim();
// 移除之前错误提示
removeValidationError(element);
// 空值不校验
if (!value) return;
const rule = validationRules[dataType];
if (!rule.pattern.test(value)) {
showValidationError(element, rule.message);
}
};
// 绑定事件
element.addEventListener('blur', validationHandler);
element.addEventListener('input', validationHandler);
// 保存引用便于清理
element._validationHandler = validationHandler;
}
/**
* 初始化表单校验功能
*/
export function initFormValidation() {
// 使用 MutationObserver 监听 DOM 变化
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.type === 'childList') {
mutation.addedNodes.forEach((node) => {
if (node.nodeType === Node.ELEMENT_NODE) {
// 处理新添加的表单元素
if (isFormElement(node)) {
setInputDefaults(node);
addInputValidation(node);
}
// 处理子元素中的表单元素
const formElements = node.querySelectorAll
? node.querySelectorAll('input, textarea')
: [];
formElements.forEach((element) => {
setInputDefaults(element);
addInputValidation(element);
});
}
});
}
});
});
// 开始观察 DOM 变化
observer.observe(document.body, {
childList: true,
subtree: true
});
// 处理已存在的表单元素
function processExistingElements() {
const elements = document.querySelectorAll('input, textarea');
elements.forEach((element) => {
setInputDefaults(element);
addInputValidation(element);
});
}
// 页面加载完成后处理现有元素
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', processExistingElements);
} else {
processExistingElements();
}
}
/**
* 判断是否为表单元素
* @param {HTMLElement} element - 元素
* @returns {boolean}
*/
function isFormElement(element) {
const tagName = element.tagName.toLowerCase();
return tagName === 'input' || tagName === 'textarea';
}
解决方案
这套工具函数的核心思想是:
-
自动属性设置 :通过 setInputDefaults 函数为不同类型的表单元素自动添加合适的默认属性,如最大长度、占位符等。
-
灵活校验规则 :通过 validationRules 对象定义各种校验规则,支持扩展自定义规则。
-
实时校验反馈 :通过 addInputValidation 函数为表单元素添加失焦和输入事件监听器,实现实时校验。
-
动态元素支持 :使用 MutationObserver 监听 DOM 变化,为动态添加的表单元素自动应用校验规则。
-
友好的错误提示 :通过 showValidationError 和 removeValidationError 函数提供直观的错误提示和视觉反馈。
使用方式非常简单,只需在应用初始化时调用 initFormValidation() 函数,并在需要校验的表单元素上添加 data-type 属性:
<input type="text" data-type="phone" />
<input type="text" data-type="email" />
<textarea data-type="username"></textarea>
这样就能自动获得完整的表单校验和格式化功能,大大减少了手动编写校验逻辑的工作量。