VBen Admin 实战:身份证号自动填充出生年月

一、需求背景

在后台管理系统中,填写用户信息时,身份证号和出生年月是常见字段。

传统做法: 用户输入身份证号,再手动选择出生年月。

优化做法: 输入身份证号后,自动解析并填充出生年月,提升用户体验。


二、效果演示

复制代码
用户输入:320106199001155647
     ↓
自动解析:第7-14位为出生年月 → 1990-01-15
     ↓
出生年月字段自动填充 → 用户无需再次选择

三、完整代码实现

1. 表单字段配置

javascript 复制代码
// ===================== 身份证号 =====================
{
  field: 'idCard',
  label: '身份证号',
  component: 'Input',
  required: true,
  colProps: col12Props,
  componentProps: ({ formModel }) => ({
    placeholder: '请输入身份证号',
    maxlength: 18,
    showCount: true,
    onChange: (e) => {
      const value = e.target.value;
      
      // 身份证号合法且达到18位时,自动解析出生年月
      if (value?.length === 18) {
        const birthStr = value.slice(6, 14); // 取第7-14位
        formModel.birthday = dayjs(birthStr).format('YYYY-MM');
      }
    },
  }),
  dynamicRules: () => [
    {
      required: true,
      message: '请输入身份证号',
      trigger: 'change',
    },
    {
      pattern: idCardReg, // 身份证正则校验
      message: '请输入正确的身份证号',
      trigger: 'change',
    },
  ],
},

// ===================== 出生年月 =====================
{
  field: 'birthday',
  label: '出生年月',
  component: 'DatePicker',
  required: true,
  colProps: col12Props,
  componentProps: {
    placeholder: '请选择出生年月',
    style: { width: '100%' },
    format: 'YYYY-MM',
    valueFormat: 'YYYY-MM',
    // 禁止选择未来时间
    disabledDate: (current) => {
      return current && current > dayjs().endOf('day');
    },
    disabled: true, // 由身份证号自动填充,不允许手动编辑
  },
},

四、核心知识点解析

1. 身份证号结构

位置 内容 示例
1-6位 行政区划代码 320106
7-14位 出生年月 19900115
15-17位 顺序码 547
18位 校验码 7

关键代码:

javascript 复制代码
const birthStr = value.slice(6, 14); // 取出生日字符串
formModel.birthday = dayjs(birthStr).format('YYYY-MM'); // 格式化为 YYYY-MM

2. 为什么 birthday 要设置 disabled: true

  • ✅ 出生年月由身份证号自动计算得出,无需用户手动修改
  • ✅ 防止用户手动修改导致数据不一致
  • ✅ 表单逻辑更清晰

3. formModel 是什么?

formModel 是 VBen Admin 表单上下文对象,通过 componentProps 的函数参数传入,可以直接修改表单其他字段的值。

javascript 复制代码
componentProps: ({ formModel }) => ({
  // 直接赋值即可触发表单更新
  onChange: (e) => {
    formModel.birthday = '1990-01';
  },
})

五、身份证号正则校验

javascript 复制代码
// 身份证号校验正则(18位)
const idCardReg = /^[1-9]\d{5}(18|19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[\dXx]$/;

校验规则说明

规则
1-6位 1-9 + 5位数字
7-14位 年月日合法格式
15-17位 3位数字
18位 数字或X/x

六、完整代码(可直接复制使用)

javascript 复制代码
import dayjs from 'dayjs';

// 身份证正则
const idCardReg = /^[1-9]\d{5}(18|19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[\dXx]$/;

// 布局配置
const col12Props = { span: 12 };

// 身份证自动填充出生年月
const idCardField = {
  field: 'idCard',
  label: '身份证号',
  component: 'Input',
  required: true,
  colProps: col12Props,
  componentProps: ({ formModel }) => ({
    placeholder: '请输入身份证号',
    maxlength: 18,
    showCount: true,
    onChange: (e) => {
      const value = e.target.value;
      if (value?.length === 18) {
        const birthStr = value.slice(6, 14);
        formModel.birthday = dayjs(birthStr).format('YYYY-MM');
      }
    },
  }),
  dynamicRules: () => [
    { required: true, message: '请输入身份证号', trigger: 'change' },
    { pattern: idCardReg, message: '请输入正确的身份证号', trigger: 'change' },
  ],
};

const birthdayField = {
  field: 'birthday',
  label: '出生年月',
  component: 'DatePicker',
  required: true,
  colProps: col12Props,
  componentProps: {
    placeholder: '请选择出生年月',
    style: { width: '100%' },
    format: 'YYYY-MM',
    valueFormat: 'YYYY-MM',
    disabledDate: (current) => current && current > dayjs().endOf('day'),
    disabled: true,
  },
};

七、注意事项

1. 为什么不用 trigger: 'blur'

身份证号输入是连续的过程,用户还在输入时不应触发校验,所以使用 change 事件,在值变化时实时校验和解析。

2. 为什么出生年月字段设置为 disabled

  • 出生年月是派生字段,由身份证号计算得出
  • 手动修改可能导致数据不一致
  • 保持表单数据的一致性和完整性

3. 日期格式化

dayjs(birthStr) 传入 19900115 会自动解析为 1990-01-15,再 .format('YYYY-MM') 输出 1990-01


八、扩展:15位身份证兼容

如果业务需要支持15位旧身份证:

javascript 复制代码
componentProps: ({ formModel }) => ({
  onChange: (e) => {
    const value = e.target.value;
    
    if (value?.length === 18) {
      // 18位身份证
      const birthStr = value.slice(6, 14);
      formModel.birthday = dayjs(birthStr).format('YYYY-MM');
    } else if (value?.length === 15) {
      // 15位身份证(第7-12位为生日)
      const birthStr = '19' + value.slice(6, 12);
      formModel.birthday = dayjs(birthStr).format('YYYY-MM');
    }
  },
}),

九、总结

技巧 说明
formModel.xxx = value 直接修改表单其他字段值
dayjs(str).format() 字符串转日期格式化
slice(6, 14) 从身份证号截取生日字段
disabled: true 禁止手动编辑派生字段
value?.length === 18 判断身份证号长度再解析

核心就是:formModel 可以在任意字段的 onChange 中修改其他字段的值,实现联动效果。

📌 作者:只道寻常

💡 技巧:VBen Admin 表单联动,用 formModel 就行!

相关推荐
SL-staff1 天前
Vue3私有化AI白板落地实战|解决政企项目智能绘图合规难题(可直接复用源码)
人工智能·低代码·开源·vue3·白板·jvs规则引擎·jvs-draw
雨季mo浅忆1 天前
Cursor快速实现上传Excel功能
前端·vue3·ai编程
ANnianStriver3 天前
PetLumina-AI 驱动的宠物生活管理平台
java·生活·vue3·springboot·ai编程·宠物·全栈开发
雨季mo浅忆4 天前
记录Vue3项目中的各类问题
前端·bug·vue3
八目蛛7 天前
八目蛛网络(免费工具网站导航)
css·vue.js·开源·vue3·html5·ai编程
颂love7 天前
Vue3基础入门
前端·学习·vue3
海市公约8 天前
Vue3组合式API中watch传值生命周期与自定义Hook实战
vue3·生命周期·watch·props·组件通信·defineexpose·自定义hook
海市公约9 天前
Vue3组合式API与响应式系统核心机制详解
vue3·computed·reactive·ref·响应式系统·composition api·script setup
小茴香35310 天前
Vue3路由权限动态管理
前端·前端框架·vue3
暗冰ཏོ14 天前
《2026 Vue2 + Vue3 完整学习指南:基础语法、路由缓存、登录拦截、项目实战与面试题》
前端·vue.js·vue·vue3·vue2