针对 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)
}
相关推荐
无限大.1 小时前
前端知识速记:节流与防抖
前端
十八朵郁金香1 小时前
【VUE案例练习】前端vue2+element-ui,后端nodo+express实现‘‘文件上传/删除‘‘功能
前端·javascript·vue.js
学问小小谢1 小时前
第26节课:内容安全策略(CSP)—构建安全网页的防御盾
运维·服务器·前端·网络·学习·安全
LCG元2 小时前
Vue.js组件开发-实现全屏图片文字缩放切换特效
前端·javascript·vue.js
还是鼠鼠3 小时前
图书管理系统 Axios 源码__新增图书
前端·javascript·vscode·ajax·前端框架·node.js·bootstrap
customer083 小时前
【开源免费】基于SpringBoot+Vue.JS体育馆管理系统(JAVA毕业设计)
java·vue.js·spring boot·后端·开源
还是鼠鼠6 小时前
图书管理系统 Axios 源码 __删除图书功能
前端·javascript·vscode·ajax·前端框架·node.js·bootstrap
轻口味6 小时前
Vue.js `Suspense` 和异步组件加载
前端·javascript·vue.js
m0_zj7 小时前
8.[前端开发-CSS]Day08-图形-字体-字体图标-元素定位
前端·css
还是鼠鼠7 小时前
图书管理系统 Axios 源码__编辑图书
前端·javascript·vscode·ajax·前端框架