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 就行!

相关推荐
蜡台2 天前
Vue3 props ref router 数据通讯传输等使用记录
前端·javascript·vue.js·vue3·router·ref
梵得儿SHI3 天前
Vue 3 工程化实战:Axios 高阶封装与样式解决方案深度指南
前端·javascript·vue3·axios·样式解决方案·api请求管理·统一请求处理
叱咤少帅(少帅)3 天前
vue3 开源项目
vue3
儒雅的烤地瓜6 天前
Vue | 一文详解Vue3中的Setup()函数
vue.js·vue3·vue2·组合式api·setup函数·option api
Irene19917 天前
ElementPlus 与成熟后台框架对比:vue-element-plus-admin、vue-pure-admin等
前端·ui·框架·vue3
终端鹿8 天前
Vue3 与第三方组件库联动:Element Plus 按需引入与二次封装
vue3·element plus·二次封装
Grocery store owner14 天前
vue3使用wangeditor上传附件以及添加表格,可以直接复制粘贴excel内容
vue3·wangeditor
floret. 小花14 天前
Vue3 知识点总结 · 2026-03-27
前端·面试·electron·学习笔记·vue3
梵得儿SHI15 天前
Vue 3 生态工具实战:UI 组件库与表单验证完全指南
前端·ui·vue3·elementplus·表单验证·antdesignvue·veevalidate
A_nanda15 天前
Vue项目升级
前端·vue3·vue2