JavaScript中的校验机制三种写法举例(如手机号码、电话号码校验)
作者:outstanding木槿
在表单验证场景中,getValueFromEvent
、pattern
和 validator
是三种不同的验证机制
方法 | 作用 | 适用场景 |
---|---|---|
getValueFromEvent | 从表单事件(如 onChange )中提取值,通常用于预处理输入数据 | 需要自定义事件值解析(如文件上传) |
pattern | 通过正则表达式对输入值进行格式校验,属于声明式规则 | 简单格式校验(如手机号、邮箱) |
validator | 通过函数实现自定义逻辑验证,支持异步操作和复杂条件判断 | 动态校验(如密码强度、联动字段) |
解析
第一位是【1】开头,第二位则是【3,4,5,7,8】,第三位则是【0-9】,第三位之后则是数字【0-9】。从而我们可以得出一个符合当前的手机号码验证正则表达式(不适用电话)。
^1(3|4|5|7|8)\d{9}$ 或者 ^1[34578]\d{9}$ 或 ^1[34578][0-9]{9}$ 或 ^1[3,4,5,7,8][0-9]{9}$
0. ^表示开始
1. 正则里面的中括号[]只能匹配其中一个
2. 如果要匹配特定几组字符串的话,那就必须使用小括号()加或|
3. |在中括号里面也是一个字符,并不代表或
4. [3457]匹配3或者4或者5或者7,而(3457)把3457这四个数当成整体匹配,若要跟前面一样可以加或(3|4|5|7)。
5. [34|57]匹配3或者4或者|或者5或者7,而(34|57)匹配34或者57。
6. \d{9}:匹配9个数字(0~9任意组合9个数字)。其中,\d 代表一个数字字符,{9} 表示前面的模式(即 \d)应重复9次。
总结
方案 | 推荐度 | 适用场景 |
---|---|---|
rules + pattern | ⭐⭐⭐⭐⭐ | 简单正则验证(推荐) |
rules + validator | ⭐⭐⭐⭐ | 复杂自定义验证 |
手动 checkPhone | ⭐ | 遗留代码或特殊需求 |
最佳实践:优先使用 Ant Design 的 rules
和 pattern
,避免手动操作 DOM 和 alert
写法1:(不推荐)
function checkPhone(){ var phone = document.getElementById('phone').value; if(!(/^1[34578]\d{9}$/.test(phone))){ alert("手机号码有误,请重填"); return false; } } 或者 function checkPhone(){ var phone = document.getElementById('phone').value; var phoneRegex = /^1(3|4|5|7|8)\d{9}$/ if(!(phoneRegex.test(phone))){ alert("手机号码有误,请重填"); return false; } } // 在提交表单时调用 handleSubmit = (e) => { e.preventDefault(); if (checkPhone()) { // 验证通过,提交表单 this.props.form.validateFields((err, values) => { if (!err) { console.log('提交数据:', values); } }); } }; // handleSubmit = () => { // const phone = document.getElementById('phone').value; // if (!this.checkPhone(phone)) { // alert("手机号码有误"); // 手动触发验证 // } // }; const FormItem = Form.Item <Row> <Col> <FormItem label='联系电话'> {getFieldDecorator('phone', { rules:[{ required: true, message: '请输入正确的联系电话!', }], initialValue: '', })( <Input id='phone' /> )} </FormItem> </Col> <Button onClick={this.handleSubmit}>提交</Button> </Row>
⚠️ 缺点:
- 直接操作 DOM(
document.getElementById
),不符合 React 的最佳实践。 - 错误提示用
alert
,用户体验较差(Ant Design 的表单错误提示更优雅)。
写法2:pattern 正则表达式
const FormItem = Form.Item <Row> <Col> <FormItem label='联系电话'> {getFieldDecorator('phone', { rules:[ { required: true, message: '请输入联系电话!' }, { pattern: /^1(3|4|5|7|8)\d{9}$/, message: '请输入11位有效手机号!' }, ], initialValue: '', })( <Input id='phone' maxLength={11} /> )} </FormItem> </Col> </Row>
✅ 优点:
- 不需要额外写
checkPhone
函数,直接用pattern
进行正则验证。 - Ant Design 会自动处理错误提示,不需要手动
alert
。
写法3:validator 自定义验证(更灵活)
(需求:除了汉字和字母不能输入以外,其他的都可输入)
const FormItem = Form.Item <Row> <Col> <FormItem label='联系电话'> {getFieldDecorator('phone', { rules:[ { required: true, message: '请输入联系电话!' }, { pattern: /^1[3-9]\d{9}$/, message: '请输入11位有效手机号!' }, { validator: (rule, value, callback) => { const reg = new RegExp('[\u4E00-\u9FA5]') const reg1 = new RegExp('[A-Za-z]') if(reg.test(value)){ callback('手机号码不能输入汉字!') } else if (reg1.test(value)){ callback('手机号码不能输入字母!') } else { callback() } } }], })( <Input id='phone' maxLength={11} /> )} </FormItem> </Col> </Row>
✅ 优点:
- 可以自定义更复杂的验证逻辑(如异步校验)。
- 仍然不需要手动操作 DOM(
document.getElementById
)。
扩展建议
国际号码支持
若需支持国际号码,可替换正则为:
pattern: /^(?:\+?86)?1[3-9]\d{9}$|^(?:\+?\d{1,3})?\d{6,15}$/
动态校验
通过 setFieldsValue
实现联动校验(如区号+座机号场景)。
防抖优化
频繁校验时建议添加防抖:
import { debounce } from 'lodash'; validator: debounce((rule, value, callback) => { ... }, 300) // 代码: rules: { username: [ { required: true, message: '必填项' }, { validator: debounce((rule, value, callback) => { if (/[^a-z]/.test(value)) callback('仅允许小写字母'); else callback(); }, 1000), trigger: 'blur' // 明确防抖触发条件。防抖场景必须声明:防抖函数需绑定明确的事件(如 blur 或 change) } ] }
场景 | 防抖配置 | 优势 |
---|---|---|
输入实时搜索 | delay: 300ms | 减少搜索接口调用 |
异步唯一性校验 | delay: 1000ms | 避免频繁请求 |
多字段联合校验 | 共享防抖实例 | 统一控制校验节奏 |
trigger: 'blur'
表示输入框失去焦点时触发校验,适合实时性要求较低的场景(如避免输入中途频繁提示)17。trigger: 'change'
会在值变化时立即校验,适合需要即时反馈的交互(如密码强度检测)场景 是否需要显式声明 原因 需要实时校验 可选(建议声明) 明确控制触发时机,避免依赖默认行为 仅提交时校验 可不写 默认行为已满足需求 防抖场景 必须声明 防抖函数需绑定明确的事件触发点(如 blur
),否则无法生效
电话号码校验,上面的pattern方法、validator方法都适用
function phoneValid(number) { // 去除任何非数字字符 const cleaned = number.replace(/\D/g, ''); // 定义正则表达式验证规则 const mobilePattern = /^1[3-9]\d{9}$/; // 手机号 const tellPattern = /^0\d{2,3}-?\d{7,8}$/; // 电话号 // 验证是否符合手机号码或座机号码格式 if (mobilePattern.test(cleaned) || tellPattern.test(cleaned)) { return true; } else { return false; } } // 示例用法 console.log(phoneValid('13800138000')); // true console.log(phoneValid('010-12345678')); // true console.log(phoneValid('12345678')); // false console.log(phoneValid('021-87654321')); // true console.log(phoneValid('18912345678')); // true
空格校验
const FormItem = Form.Item <Row> <Col> <FormItem label='联系电话'> {getFieldDecorator('phone', { getValueFormEvent: (e) => e.target.value.replace(/^\s+|\s$/g,'') initialValue: '', })( <Input id='phone' /> )} </FormItem> </Col> </Row> // " hello world ".replace(/^\s+|\s+$/g, ""); // 输出 "hello world":ml-citation{ref="1,3" data="citationList"}
语法 | 含义 | 示例匹配场景 | |
---|---|---|---|
^\s+ | 匹配字符串开头的1个或多个空白字符(空格、制表符、换行符等) | " hello" 中的开头空格 | |
\s+$ | 匹配字符串末尾的1个或多个空白字符 | "world " 中的末尾空格 | |
` | ` | 逻辑“或”操作符,匹配两者之一 | 同时处理开头和末尾空格 |
g | 全局匹配模式,替换所有符合条件的内容(而非仅第一个) | 多次替换 |
\s
匹配单个空白字符,包括:- 空格(
- 制表符(
\t
) - 换行符(
\n
) - 换页符(
\f
)等。
注:\S
表示其反向匹配(非空白字符)。
- 空格(
^
和$
^
匹配字符串的起始位置(需在开头)。$
匹配字符串的结束位置(需在末尾)。
+
表示前面的字符(\s
)至少出现1次(等价于{1,}
)若需严格匹配纯空格(不含制表符等),可用
[ ]+
替代\s+
在拆分字符串时,
\s
常用于分割单词(如split(/\s+/)
)正则表达式 作用 区别 /\s+/g
匹配所有连续空白字符 不限定位置,包括中间空格3 /^\s+/g
仅匹配开头空白字符 忽略末尾空格3 /\s+$/g
仅匹配末尾空白字符 忽略开头空格
总结
到此这篇关于JavaScript中的校验机制三种写法的文章就介绍到这了,更多相关JS手机号码、电话号码校验内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!