vue.js实现身份证号码验证

admin 101 0
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"),用于验证身份证号码的正确性

校验码算法

校验码是通过以下步骤计算得出的:

  1. 将前17位数字分别乘以对应的加权因子(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2)
  2. 计算乘积之和,然后对11取余
  3. 根据余数匹配校验码,对应关系为:[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,