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

相关推荐
吴声子夜歌15 小时前
Vue3——网络框架Axios的应用
javascript·vue3·axios
赵庆明老师9 天前
vben开发入门6:tsconfig.json
json·vue3·vben
赵庆明老师9 天前
vben开发入门5:vite.config.ts
前端·html·vue3·vben
沙振宇10 天前
【Web】使用Vue3+PlayCanvas开发3D游戏(十二)渲染PCD点云可视化模型
3d·vue3·点云·pcd
是席木木啊13 天前
告别console.log!Vue3项目日志框架选型指南
前端·vue3·日志框架
程序员-南13 天前
解决 Vue3 中 keep-alive 缓存问题的方法
缓存·vue3
qq_120840937114 天前
Three.js 模型加载稳定性实战:从资源失败到可用发布的工程化方案
前端·javascript·vue.js·vue3·three.js
qq_120840937115 天前
Three.js 模型加载与线上稳定性实战:路径、跨域、缓存与降级全链路指南
开发语言·javascript·缓存·vue3
qq_120840937115 天前
Vue3 + Three.js 实战入门:从零搭建可交互3D场景(含模型加载与性能优化)
javascript·3d·vue3·交互
qq_120840937115 天前
Vue3 + Three.js 入门实战:从 0 到 1 搭建可交互的 3D 场景(含模型加载与性能优化)
javascript·3d·vue3·交互·webgl·gltf