需求描述
一、业务需求背景
- 原始项目现状
目前项目为Vue2后台管理系统,项目二次封装通用业务组件w-range-picker(业务自定义组件,底层封装el-date-picker),原有仅支持时间范围查询,存在两个线上问题:
- 缺少按日、按月查询切换功能,报表、能耗统计只能固定时间筛选,查询灵活性差
- 未做日期限制,用户可选择当月、当天之后的未来日期,后端无数据,频繁报接口空数据、参数异常
- 原生el-date-picker禁用逻辑存在时区bug,零点判断不准,偶尔出现当天无法选中问题
- 本次开发需求
- 优化自研组件 w-range-picker,新增维度切换:按日查询 / 按月查询
- 时间强校验:禁止选择当天之后日期;按月模式禁止选择当月之后月份
- 保留原有水务大屏样式、组件双向绑定逻辑,零侵入改造,兼容历史所有业务页面
- 修复日期时间戳时区偏移bug,避免临界日期禁用异常
二、前置知识点科普
- w-range-picker组件来源
很多小伙伴疑惑该组件不是Element、AntD官方组件,这里统一说明:
- w前缀含义:项目自定义业务前缀,区分UI库原生组件
- 底层封装:二次封装 ElementUI el-date-picker,拓展业务快捷时间、样式适配、日期格式化通用逻辑
- 存放地址:src/components/w/ 全局注册公共业务组件,全局无需手动引入
- 日期禁用核心原理
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);