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

相关推荐
哆啦A梦15881 天前
java项目在后端做跨域配置
java·vue3
路光.3 天前
uniappVue2升级Vue3内存溢出解决方式
vue·vue3·uniapp
沙振宇3 天前
【Web】使用 Vue3+PlayCanvas 开发 3D 游戏(五)3D 模型鼠标交互控制
3d·vue3·鼠标·playcanvas
nibabaoo6 天前
前端开发攻略---Vue3项目中实现指定区域的打印预览与 PDF 导出功能
vue3·js·打印预览pdf
nibabaoo6 天前
前端开发攻略---在 Vue 3 项目中使用 vue-i18n 实现国际化多语言
前端·javascript·国际化·i18n·vue3
沙振宇7 天前
【Web】使用Vue3+PlayCanvas开发3D游戏(四)3D障碍物躲避游戏2-模型加载
游戏·3d·vue3·vite·playcanvas
SuperEugene8 天前
Vue3 中后台实战:VXE Table 从基础表格到复杂业务表格全攻略 | Vue生态精选篇
前端·vue.js·状态模式·vue3·vxetable
p5l2m9n4o6q8 天前
Vue3后台管理系统布局实战:从零搭建Element Plus左右布局(含Pinia状态管理)
vue3·pinia·element plus·viewui·后台管理系统
梵得儿SHI8 天前
Vue3 生态工具实战进阶:API 请求封装 + 样式解决方案全攻略(Axios/Sass/CSS Modules)
前端·css·vue3·sass·api请求·样式解决方案·组合式api管理