You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue框架下实现dd.mm.yy日期格式的实时输入正则验证与非法输入拦截

实时验证dd.mm.yy格式日期输入(Vue.js实现)

我来帮你解决这个实时日期输入验证的问题——你需要的是逐字符拦截非法输入+自动维护格式的逻辑,而不是只在输入完成后校验。下面是基于Vue.js的完整解决方案:

核心思路

要实现实时拦截,我们需要抛弃仅依赖change事件的方式,改用input(输入后实时处理)和keydown(输入前拦截非法按键)组合的方案:

  1. 拦截非数字、非点的输入(比如字母、特殊符号)
  2. 自动维护dd.mm.yy的格式:输入2位日之后自动补点,输入2位月之后自动补点
  3. 实时校验日、月的数值合法性(比如日不能超过31,月不能超过12)

完整代码实现

模板部分

替换原有的input标签,用v-model绑定数据,同时绑定input和keydown事件:

<input 
  v-model="dateInput"
  @input="validateOnInput"
  @keydown="handleKeyDown"
  placeholder="dd.mm.yy"
  maxlength="8"
/>

脚本部分

在Vue组件中实现两个核心方法,以及最终的提交验证:

export default {
  data() {
    return {
      dateInput: ''
    }
  },
  methods: {
    // 输入前拦截非法按键
    handleKeyDown(e) {
      // 允许的按键:数字、点、退格/删除、方向键、Tab
      const allowedKeys = ['0','1','2','3','4','5','6','7','8','9','.', 'Backspace', 'Delete', 'ArrowLeft', 'ArrowRight', 'Tab'];
      if (!allowedKeys.includes(e.key)) {
        e.preventDefault(); // 阻止非法输入
        return;
      }

      // 当输入到第2位(日)或第5位(月)时,自动补点(如果用户没输点)
      const currentLength = this.dateInput.length;
      if ((currentLength === 2 || currentLength === 5) && e.key !== '.' && !['Backspace','Delete','ArrowLeft','ArrowRight'].includes(e.key)) {
        e.preventDefault();
        this.dateInput += '.' + e.key;
      }
    },
    // 输入后实时格式化和校验数值
    validateOnInput() {
      // 第一步:过滤掉所有非数字和点的字符
      let cleanedValue = this.dateInput.replace(/[^0-9.]/g, '');
      
      // 第二步:拆分日期部分,处理每个部分的合法性
      let parts = cleanedValue.split('.').filter(part => part); // 过滤空的部分(比如连续点的情况)
      let formattedValue = '';

      // 处理日部分:最多2位,不能超过31
      if (parts[0]) {
        let day = parts[0].slice(0, 2);
        if (parseInt(day) > 31) day = '31';
        formattedValue += day;
        // 日输入完成后自动补点
        if (day.length === 2) formattedValue += '.';
      }

      // 处理月部分:最多2位,不能超过12
      if (parts[1]) {
        let month = parts[1].slice(0, 2);
        if (parseInt(month) > 12) month = '12';
        formattedValue += month;
        // 月输入完成后自动补点
        if (month.length === 2) formattedValue += '.';
      }

      // 处理年部分:最多2位
      if (parts[2]) {
        formattedValue += parts[2].slice(0, 2);
      }

      // 最后限制总长度不超过8(dd.mm.yy共8个字符)
      this.dateInput = formattedValue.slice(0, 8);
    },
    // 最终提交时的完整验证(可选,用于确保日期完全合法)
    isDateValid() {
      const dateRegex = /^(0[1-9]|[12][0-9]|3[01])\.(0[1-9]|1[012])\.[0-9]{2}$/;
      if (!dateRegex.test(this.dateInput)) return false;
      
      // 可选:进一步校验日期的有效性(比如2月不能有30号)
      const [day, month, year] = this.dateInput.split('.').map(Number);
      const testDate = new Date(2000 + year, month - 1, day);
      return testDate.getDate() === day && testDate.getMonth() === month - 1;
    },
    // 你的原有change逻辑可以改成这样
    changeFunction() {
      if (this.isDateValid()) {
        // 执行合法操作
        console.log('日期合法:', this.dateInput);
      } else {
        // 执行错误提示
        console.log('日期格式不正确');
      }
    }
  }
}

方案优势

  • 实时拦截:用户输入字母或非法符号时直接被阻止,不会显示在输入框中
  • 自动格式化:无需用户手动输入点,输完2位日/月后自动补全格式
  • 数值校验:避免用户输入32号、13月这类无效数值
  • 友好体验:允许用户使用退格、方向键等操作,不破坏正常输入流程

内容的提问来源于stack exchange,提问作者Marko

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 15:42:36