【功能开发】添加按月按日查询器,禁用当月当天之后的选择

📅 2026/7/3 5:02:41 👁️ 阅读次数 📝 编程学习
【功能开发】添加按月按日查询器,禁用当月当天之后的选择

需求描述

一、业务需求背景

  1. 原始项目现状
    目前项目为Vue2后台管理系统,项目二次封装通用业务组件w-range-picker(业务自定义组件,底层封装el-date-picker),原有仅支持时间范围查询,存在两个线上问题:
  • 缺少按日、按月查询切换功能,报表、能耗统计只能固定时间筛选,查询灵活性差
  • 未做日期限制,用户可选择当月、当天之后的未来日期,后端无数据,频繁报接口空数据、参数异常
  • 原生el-date-picker禁用逻辑存在时区bug,零点判断不准,偶尔出现当天无法选中问题
  1. 本次开发需求
  2. 优化自研组件 w-range-picker,新增维度切换:按日查询 / 按月查询
  3. 时间强校验:禁止选择当天之后日期;按月模式禁止选择当月之后月份
  4. 保留原有水务大屏样式、组件双向绑定逻辑,零侵入改造,兼容历史所有业务页面
  5. 修复日期时间戳时区偏移bug,避免临界日期禁用异常

二、前置知识点科普

  1. w-range-picker组件来源
    很多小伙伴疑惑该组件不是Element、AntD官方组件,这里统一说明:
  • w前缀含义:项目自定义业务前缀,区分UI库原生组件
  • 底层封装:二次封装 ElementUI el-date-picker,拓展业务快捷时间、样式适配、日期格式化通用逻辑
  • 存放地址:src/components/w/ 全局注册公共业务组件,全局无需手动引入
  1. 日期禁用核心原理
    el-date-picker 提供 disabledDate 回调函数:
  • 返回 true:禁用当前日期,不可点击
  • 返回 false:放开日期,正常可选
  • 踩坑重点:禁止直接使用 Date.now() 判断!携带时分秒,会造成当天傍晚触发禁用,必须归一化日期零点比对

代码解决

1.为w-range-picker组件加入:disabledDate属性并绑定对应method

:disabledDate="disableMonthFn"
<template#ticketTime><divstyle="display:flex;gap:8px;align-items:center;width:100%;"><!-- 切换开关 --><w-radio-groupv-model="dateMode"@change="handleDateModeChange"><w-radiovalue="month">按月</w-radio><w-radiovalue="day">按日</w-radio></w-radio-group><!-- 月份选择器 --><w-range-pickerv-if="dateMode === 'month'":mode="['month', 'month']"format="YYYY-MM"v-model="yearMode":open="yearShowOne"cell-class-name="cellClassName":allowClear="false":disabledDate="disableMonthFn"@openChange="openChangeOne"@panelChange="panelChangeOne"style="flex:1;min-width:280px"/><!-- 日期选择器 --><w-range-pickerv-elseformat="YYYY-MM-DD"v-model="dayRange":allowClear="false":disabledDate="disableDayFn"@change="handleDayChange"style="flex:1;min-width:280px"/></div></template>

2.在method下写入对应方法

disableDayFn(currentDate){if(!currentDate)returnfalse;consttoday=moment().startOf('day');constisDisabled=currentDate.isAfter(today);returnisDisabled;},

效果展示

拓展

只禁用明天及以后,今天可选:

constisDisabled=currentDate.isAfter(today);

想禁用今天 + 未来,只能选过去:

constisDisabled=currentDate.isSameOrAfter(today);

禁用所有过去日期,只能选今天和未来:

constisDisabled=currentDate.isBefore(today);