Vue.js实现身份证号码验证,需综合格式、地区码、出生日期及校验位逻辑,通过自定义方法或组件封装,先校验18位长度,前17位为数字、第18位数字或“X”;再验证前6位地区码有效性(可引入地区码列表);接着检查第7-14位出生日期是否合法(如不早于1900年、不超过当前日期);最后用ISO 7064标准计算校验位,与第18位比对,结合v-model绑定输入数据,实时反馈验证结果,提升表单交互体验,适用于用户信息录入等场景。
Vue.js 实现身份证号码验证:完整步骤与代码示例
在用户注册、信息填写、实名认证等业务场景中,身份证号码验证是确保数据准确性和安全性的重要环节,本文将详细介绍如何使用 Vue.js 实现身份证号码的全面验证,包括格式验证、日期有效性验证、校验码验证,并提供完整的代码示例,帮助开发者快速集成到项目中。
身份证号码基本规则
在实现验证之前,我们需要深入了解身份证号码的规则(以18位身份证为例):
结构组成
18位身份证由 17位本体码 和 1位校验码 组成,具体结构如下:
- 前6位:地址码(数字),表示编码对象常住户口所在县(市、旗、区)的行政区划代码
- 中间8位:出生日期码(格式:YYYYMMDD),表示编码对象的出生年月日
- 后3位:顺序码(奇数分配给男性,偶数分配给女性),表示在同一地址码所标识的区域范围内,对同年、同月、同日出生的人编定的顺序号
- 最后1位:校验码(可能是数字或"X"),用于验证身份证号码的正确性
校验码算法
校验码是通过以下步骤计算得出的:
- 将前17位数字分别乘以对应的加权因子(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2)
- 计算乘积之和,然后对11取余
- 根据余数匹配校验码,对应关系为:
[1, 0, X, 9, 8, 7, 6, 5, 4, 3, 2]
15位身份证
早期版本的15位身份证已逐步淘汰,但在部分场景仍需兼容,其特点包括:
- 无校验码
- 出生日期为6位(YYMMDD)
- 最后一位为顺序码
Vue.js 实现身份证验证步骤
创建基础组件
我们创建一个可复用的 Vue 组件,包含输入框和验证结果提示,组件使用 v-model 双向绑定身份证号码,并通过输入事件触发验证。
<template>
<div class="id-card-validator">
<label for="idCard">身份证号码:</label>
<input
type="text"
id="idCard"
v-model="idCardNumber"
placeholder="请输入15位或18位身份证号码"
@input="validateIdCard"
maxlength="18"
/>
<div class="validation-result" :class="resultClass">
{{ validationMessage }}
</div>
<div v-if="isValid" class="additional-info">
<p>性别:{{ gender }}</p>
<p>出生日期:{{ formattedBirthDate }}</p>
<p>年龄:{{ age }}岁</p>
</div>
</div>
</template>
<script>
export default {
data() {
return {
idCardNumber: "", // 绑定的身份证号码
validationMessage: "", // 验证结果提示
isValid: false, // 验证是否通过
gender: "", // 性别信息
birthDate: null, // 出生日期对象
age: 0, // 年龄
};
},
computed: {
// 动态计算结果样式类
resultClass() {
return {
"valid": this.isValid,
"invalid": !this.isValid && this.validationMessage !== "",
};
},
// 格式化出生日期显示
formattedBirthDate() {
if (!this.birthDate) return "";
return `${this.birthDate.getFullYear()}年${this.birthDate.getMonth() + 1}月${this.birthDate.getDate()}日`;
},
},
methods: {
// 验证身份证号码
validateIdCard() {
const value = this.idCardNumber.trim();
if (!value) {
this.resetValidation();
return;
}
// 1. 验证基本格式(15位或18位,仅允许数字和X)
if (!/^\d{15}(\d{2}[\dXx])?$/.test(value)) {
this.validationMessage = "身份证号码格式不正确(应为15位或18位)";
this.isValid = false;
return;
}
// 2. 验证日期有效性
if (!this.validateDate(value)) {
this.validationMessage = "身份证号码中的出生日期无效";
this.isValid = false;
return;
}
// 3. 验证校验码(仅18位)
if (value.length === 18 && !this.validateCheckCode(value)) {
this.validationMessage = "身份证号码校验码错误";
this.isValid = false;
return;
}
// 4. 提取性别信息
this.extractGender(value);
// 全部通过验证
this.validationMessage = "身份证号码验证通过";
this.isValid = true;
},
// 重置验证状态
resetValidation() {
this.validationMessage = "";
this.isValid = false;
this.gender = "";
this.birthDate = null;
this.age = 0;
},
// 验证日期有效性
validateDate(idCard) {
if (idCard.length === 15) {
// 15位身份证:出生日期为6位(YYMMDD),需转换为4位年份(假设19XX年)
const year = "19" + idCard.substring(6, 8);
const month = idCard.substring(8, 10);
const day = idCard.substring(10, 12);
const date = this.isValidDate(year, month, day);
if (date) {
this.birthDate = date;
this.calculateAge(date);
}
return date;
} else if (idCard.length === 18) {
// 18位身份证:出生日期为8位(YYYYMMDD)
const year = idCard.substring(6, 10);
const month = idCard.substring(10, 12);
const day = idCard.substring(12, 14);
const date = this.isValidDate(year, month, day);
if (date) {
this.birthDate = date;
this.calculateAge(date);
}
return date;
}
return false;
},
// 验证日期是否有效
isValidDate(year, month, day) {
const date = new Date(year, month - 1, day);
const isValid = (
date.getFullYear() === parseInt(year) &&
date.getMonth() + 1 === parseInt(month) &&
date.getDate() === parseInt(day)
);
// 检查日期是否合理(如2月30日)
if (isValid) {
const now = new Date();
const birthYear = parseInt(year);
// 简单的年份范围检查
if (birthYear < 1900 || birthYear > now.getFullYear()) {
return false;
}
return true;
}
return false;
},
// 计算年龄
calculateAge(birthDate) {
const now = new Date();
let age = now.getFullYear() - birthDate.getFullYear();
const monthDiff = now.getMonth() - birthDate.getMonth();
if (monthDiff < 0 || (monthDiff === 0 && now.getDate() < birthDate.getDate())) {
age--;
}
this.age = age;
},
// 验证校验码
validateCheckCode(idCard) {
// 加权因子
const weights = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4,