针对 el-date picker pickerOptions 快捷选项的超级方法

提供快捷的配置,支持原子组合,高级用法支持用户自定义配置项

demo

bash 复制代码
import { generateShortCuts } from './date-shortcuts.js'
...
pickerOptions: {
  shortcuts: generateShortCuts({type: 'day'})
}
...

date-shortcuts 文件

bash 复制代码
import moment from 'moment'
// 日期快捷配置
export const dateConfig = {
  day: [
    {
      text: '今天',
      value: 'currentDay',
      diff: 0
    },
    {
      text: '昨天',
      value: 'lastDay',
      diff: 'lastDay'
    },
    {
      text: '近3天',
      value: 'threeDay',
      diff: 3
    },
    {
      text: '近7天',
      value: 'sevenDay',
      diff: 7
    },
    {
      text: '近15天',
      value: 'fifteenDay',
      diff: 15
    },
    {
      text: '近30天',
      value: 'thirtyDay',
      diff: 30
    },
    {
      text: '近60天',
      value: 'sixtyDay',
      diff: 60
    },
    {
      text: '近90天',
      value: 'ninetyDay',
      diff: 90
    }
  ],
  week: [
    {
      text: '本周',
      value: 'currentWeek',
      diff: 0
    },
    {
      text: '上周',
      value: 'lastWeek',
      diff: 1
    },
    {
      text: '上上周',
      value: 'beforeLastWeek',
      diff: 2
    }
  ],
  month: [
    {
      text: '当月',
      value: 'currentMonth',
      diff: 0
    },
    {
      text: '上月',
      value: 'lastMonth',
      diff: 'lastMonth'
    },
    {
      text: '近3月',
      value: 'beforeThreeMonth',
      diff: 'beforeThreeMonth'
    },
    {
      text: '一月',
      value: 'oneMonth',
      diff: 1
    },
    {
      text: '二月',
      value: 'twoMonth',
      diff: 2
    },
    {
      text: '三月',
      value: 'threeMonth',
      diff: 3
    },
    {
      text: '四月',
      value: 'fourMonth',
      diff: 4
    },
    {
      text: '五月',
      value: 'fiveMonth',
      diff: 5
    },
    {
      text: '六月',
      value: 'sixMonth',
      diff: 6
    },
    {
      text: '七月',
      value: 'sevenMonth',
      diff: 7
    },
    {
      text: '八月',
      value: 'eightMonth',
      diff: 8
    },
    {
      text: '九月',
      value: 'nineMonth',
      diff: 9
    },
    {
      text: '十月',
      value: 'tenMonth',
      diff: 10
    },
    {
      text: '十一月',
      value: 'elevenMonth',
      diff: 11
    },
    {
      text: '十二月',
      value: 'twelveMonth',
      diff: 12
    }
  ],
  quarter: [
    {
      text: '本季度',
      value: 'currentQuarter',
      diff: 0
    },
    {
      text: '上季度',
      value: 'lastQuarter',
      diff: 'lastQuarter'
    },
    {
      text: '第一季度',
      value: 'oneQuarter',
      diff: 1
    },
    {
      text: '第二季度',
      value: 'twoQuarter',
      diff: 2
    },
    {
      text: '第三季度',
      value: 'threeQuarter',
      diff: 3
    },
    {
      text: '第四季度',
      value: 'fourQuarter',
      diff: 4
    }
  ],
  year: [
    {
      text: '今年',
      value: 'currentYear',
      diff: 0
    },
    {
      text: '近半年',
      value: 'halfYear',
      diff: 0.5
    },
    {
      text: '近1年',
      value: 'oneYear',
      diff: 1
    },
    {
      text: '近2年',
      value: 'twoYear',
      diff: 2
    },
    {
      text: '近3年',
      value: 'threeYear',
      diff: 3
    }
  ],
  defaultDay: [ // 默认天配置
    {
      text: '今天',
      value: 'currentDay',
      diff: 0
    },
    {
      text: '昨天',
      value: 'lastDay',
      diff: 'lastDay'
    },
    {
      text: '本周',
      value: 'currentWeek',
      diff: 0
    },
    {
      text: '上周',
      value: 'lastWeek',
      diff: 1
    },
    {
      text: '当月',
      value: 'currentMonth',
      diff: 0
    },
    {
      text: '上月',
      value: 'lastMonth',
      diff: 'lastMonth'
    },
    {
      text: '近30天',
      value: 'thirtyDay',
      diff: 30
    },
    {
      text: '近半年',
      value: 'halfYear',
      diff: 0.5
    }
  ],
  defaultMonth: [ // 默认月配置
    {
      text: '近半年',
      value: 'halfYear',
      diff: 0.5
    },
    {
      text: '近3月',
      value: 'beforeThreeMonth',
      diff: 'beforeThreeMonth'
    },
    {
      text: '上月',
      value: 'lastMonth',
      diff: 'lastMonth'
    },
    {
      text: '当月',
      value: 'currentMonth',
      diff: 0
    }
  ]
}

// y,d 转大写
export const transFormat = (fmt) => {
  return fmt.replace(/y/g, 'Y').replace(/d/g, 'D')
}
// picker 点击事件调用方法
export const onClickPicker = (params) => {
  let { picker, option, format } = params
  picker.visible = true
  let fmt = transFormat(format)
  let s = moment()
  let e = moment()
  let { value, diff } = option
  if (value.includes('Day')) {
    if (typeof diff === 'number') {
      s = diffDay(diff)
    } else {
      if (diff === 'lastDay') {
        s = moment().subtract(1, 'day')
        e = moment().subtract(1, 'day')
      }
    }
  } else if (value.includes('Week')) {
    if (diff) {
      const weekRange = diffWeek(diff)
      s = weekRange[0]
      e = weekRange[1]
    } else {
      s = moment().startOf('week')
    }
  } else if (value.includes('Month')) {
    if (diff) {
      if (typeof diff === 'number') {
        const monthRange = diffMonth(diff)
        s = monthRange[0]
        e = monthRange[1]
      } else {
        if (diff === 'lastMonth') {
          s = moment().subtract(1, 'month').startOf('month')
          e = moment().subtract(1, 'month').endOf('month')
        } else if (diff === 'beforeThreeMonth') {
          s = moment().subtract(3, 'month').startOf('month')
        } else if (diff === 'checkMonth') {
          return option.onClick()
        }
      }
    } else {
      s = moment().startOf('month')
    }
  } else if (value.includes('Quarter')) {
    const currentQuarter = moment().quarter()
    if (diff) {
      if (typeof diff === 'number') {
        const quarterRange = diffQuarter(diff)
        s = quarterRange[0]
        e = quarterRange[1]
      } else {
        if (diff === 'lastQuarter') {
          s = moment().quarter(currentQuarter - 1).startOf('quarter')
          e = moment().quarter(currentQuarter - 1).endOf('quarter')
        }
      }
    } else {
      s = moment().quarter(currentQuarter).startOf('quarter')
    }
  } else if (value.includes('Year')) {
    s = diffYear(diff)
  }
  let start = s.set({ hour: 0, minute: 0, second: 0, millisecond: 0 }).format(fmt)
  let end = e.set({ hour: 23, minute: 59, second: 59, millisecond: 59 }).format(fmt)
  picker.$emit('pick', [start, end])
}

// 此刻点击
export const onClickCurrentPicker = (picker, format) => {
  const currentTime = moment().format(format)
  picker.$emit('pick', [currentTime, currentTime])
}
// 计算天方法
export const diffDay = (diff) => {
  return diff ? moment().subtract(diff, 'day') : moment().startOf('day')
}
// 计算周方法
export const diffWeek = (diff) => {
  return [moment().subtract(diff, 'weeks').startOf('week'), moment().subtract(diff, 'weeks').endOf('week')]
}
// 计算月方法
export const diffMonth = (diff) => {
  return [moment().month(diff - 1).startOf('month'), moment().month(diff - 1).endOf('month')]
}
// 计算季度
export const diffQuarter = (diff) => {
  return [moment().quarter(diff).startOf('quarter'), moment().quarter(diff).endOf('quarter')]
}
// 计算年方法
export const diffYear = (diff) => {
  return diff ? moment().subtract(diff, 'years') : moment().startOf('year')
}
/**
 * 生成日期快捷配置
 * @param {*} 对象包含以下参数
 * @type: String 非必填(默认 defaultDay): defaultDay, defaultMonth, day, week, month, quarter, year 可以自由组合,以 - 连接,如:day-month;
 * @includes: Array 非必填(默认[]): 展示那些快捷方式,不填展示类型映射的所有快捷方式
 * @excludes: Array 非必填(默认[]): 排除那些快捷方式
 * @custom: Array 非必填(默认[]): 自定义,格式[{text: 'hello', onClick: function}]
 * @format:String 非必填(默认YYYY-MM-DD HH:mm:ss):格式化
 * @showCurrent: Boolean 非必填(默认 true):控制"此刻"显示
 */
export const generateShortCuts = (params) => {
  let shortcuts = []
  let { type = 'defaultDay', showCurrent = true, format = 'YYYY-MM-DD HH:mm:ss' } = params
  try {
    shortcuts = getPreConfig(params)
    if (showCurrent) {
      shortcuts.push({
        text: '此刻',
        onClick: (picker) => onClickCurrentPicker(picker, format)
      })
    }
    if (type.includes('defaultDay')) {
      shortcuts.push({
        text: '选择月',
        onClick: (picker) => {
          picker.visible = true
          picker.shortcuts = [{
            text: '返回',
            onClick: (picker) => {
              picker.visible = true
              picker.shortcuts = generateShortCuts(params)
              let shortcutElements = document.querySelectorAll('.el-picker-panel__shortcut')
              shortcutElements.forEach(element => {
                element.style.lineHeight = '28px' // 设置行高为 28px,恢复行高
              })
            }
          }].concat(getPreConfig({ type: 'month', excludes: ['currentMonth', 'lastMonth', 'beforeThreeMonth'] }))
          let shortcutElements = document.querySelectorAll('.el-picker-panel__shortcut')
          shortcutElements.forEach(element => {
            element.style.lineHeight = '26px' // 设置行高为 26px,避免"十二月"被遮盖
          })
        }
      })
    }
    return shortcuts
  } catch (e) {
    console.warn(`generateShortCuts catch ${e}`)
    return shortcuts
  }
}

// 计算配置
export const getPreConfig = (params) => {
  let { type = 'defaultDay', includes = [], excludes = [], custom = [], format = 'YYYY-MM-DD HH:mm:ss' } = params || {}
  let config = []
  let shortcuts = []
  let sortConfigs = []
  let types = type.split('-')
  types.forEach(type => {
    if (dateConfig[type]) {
      config = config.concat(dateConfig[type])
    } else {
      console.warn(`${type} not exit for dateConfig`)
    }
  })
  if (excludes.length) config = config.filter(item => !excludes.includes(item.value))
  if (includes.length) {
    includes.forEach(item => {
      let target = config.find(shortItem => shortItem.value === item)
      if (target) sortConfigs.push(target)
    })
  } else {
    sortConfigs = config
  }
  sortConfigs.forEach(item => {
    shortcuts.push({
      text: item.text,
      onClick: (picker) => onClickPicker({ picker, option: item, format })
    })
  })
  return shortcuts.concat(custom)
}
相关推荐
鸡鸭扣14 分钟前
DRF/Django+Vue项目线上部署:腾讯云+Centos7.6(github的SSH认证)
前端·vue.js·python·django·腾讯云·drf
龙井茶Sky17 分钟前
验证码与登录过程逻辑学习总结
前端·登录·验证码
Edward Nygma1 小时前
springboot3+vue3融合项目实战-大事件文章管理系统-更新用户密码
android·开发语言·javascript
sunbyte1 小时前
Three.js + React 实战系列 - 职业经历区实现解析 Experience 组件✨(互动动作 + 3D 角色 + 点击切换动画)
javascript·react.js·3d
2401_831943322 小时前
Element Plus对话框(ElDialog)全面指南:打造灵活弹窗交互
前端·vue.js·交互
计算机学姐2 小时前
基于SpringBoot的在线教育管理系统
java·vue.js·spring boot·后端·mysql·spring·mybatis
strongwyy2 小时前
DA14585墨水屏学习(2)
前端·javascript·学习
好青崧2 小时前
冒泡排序的原理
前端
椒盐螺丝钉2 小时前
CSS 基础知识分享:从入门到注意事项
前端·css
球球和皮皮2 小时前
Babylon.js学习之路《一、初识 Babylon.js:什么是 3D 开发与 WebGL 的完美结合?》
javascript·3d·前端框架·ar·vr