需求:使用el-date-picker组件时显示农历数据。

element ui 日期组件 默认显示当天 elementui日历插件_javascript

 修改思路:提取element-ui源码,添加相应样式,农历转化数据写在公共文件中引用。

一、提取组件

  1. 将在node_modules > element-ui > packages 下的 date-picker组件文件夹的内容复制一份到自己项目的components目录下 ;
  2. main.js文件夹中导入放到components文件夹下的date-picker组件;(注意使用顺序)
// 导入修改本地后的element的datepicker
import DatePicker from '@/components/datePicker/index'
Vue.use(ElementUI)
Vue.use(DatePicker)
  1. 注释date-picker>src>basic>time-spinnner和date-picker>src>panel>time-select中引入
    scrollbar代码;(解决编译报错)
import { getRangeHours, getRangeMinutes, modifyTime } from 'element-ui/src/utils/date-util';
  // import ElScrollbar from 'element-ui/packages/scrollbar';
  import RepeatClick from 'element-ui/src/directives/repeat-click';

  export default {
    // components: { ElScrollbar },
  1. 在date-picker>src>panel>date文件style中添加样式;(解决时间选择控件在弹出框中显示问题)
<style lang="scss">
.el-picker-panel {
  z-index: 9999 !important;
}
</style>

二、添加农历数据,修改组件数据

  1. 农历转化数据写在utils>date.js文件中;
/**
 * @1900-2100区间内的公历、农历互转
 * @charset UTF-8
 * @公历转农历:calendar.solar2lunar(1987,11,01); //[you can ignore params of prefix 0]
 * @农历转公历:calendar.lunar2solar(1987,09,10); //[you can ignore params of prefix 0]
 */
export default {
  /**
   * 农历1900-2100的润大小信息表
   * @Array Of Property
   * @return Hex
   */
  lunarInfo: [0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2, 0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 0x0ada2, 0x095b0, 0x14977, 0x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970, 0x06566, 0x0d4a0, 0x0ea50, 0x16a95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0, 0x1c8d7, 0x0c950, 0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557, 0x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5b0, 0x14573, 0x052b0, 0x0a9a8, 0x0e950, 0x06aa0, 0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0, 0x096d0, 0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b6a0, 0x195a6, 0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570, 0x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x05ac0, 0x0ab60, 0x096d5, 0x092e0, 0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 0x092d0, 0x0cab5, 0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930, 0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 0x0d530, 0x05aa0, 0x076a3, 0x096d0, 0x04afb, 0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45, 0x0b5a0, 0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0, 0x14b63, 0x09370, 0x049f8, 0x04970, 0x064b0, 0x168a6, 0x0ea50, 0x06b20, 0x1a6c4, 0x0aae0, 0x092e0, 0x0d2e3, 0x0c960, 0x0d557, 0x0d4a0, 0x0da50, 0x05d55, 0x056a0, 0x0a6d0, 0x055d4, 0x052d0, 0x0a9b8, 0x0a950, 0x0b4a0, 0x0b6a6, 0x0ad50, 0x055a0, 0x0aba4, 0x0a5b0, 0x052b0, 0x0b273, 0x06930, 0x07337, 0x06aa0, 0x0ad50, 0x14b55, 0x04b60, 0x0a570, 0x054e4, 0x0d160, 0x0e968, 0x0d520, 0x0daa0, 0x16aa6, 0x056d0, 0x04ae0, 0x0a9d4, 0x0a2d0, 0x0d150, 0x0f252, 0x0d520, ], //2100

  /**
   * 公历每个月份的天数普通表
   * @Array Of Property
   * @return Number
   */
  solarMonth: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],

  /**
   * 天干地支之天干速查表
   * @Array Of Property trans["甲","乙","丙","丁","戊","己","庚","辛","壬","癸"]
   * @return Cn string
   */
  Gan: ['\u7532', '\u4e59', '\u4e19', '\u4e01', '\u620a', '\u5df1', '\u5e9a', '\u8f9b', '\u58ec', '\u7678', ],

  /**
   * 天干地支之地支速查表
   * @Array Of Property
   * @trans["子","丑","寅","卯","辰","巳","午","未","申","酉","戌","亥"]
   * @return Cn string
   */
  Zhi: ['\u5b50', '\u4e11', '\u5bc5', '\u536f', '\u8fb0', '\u5df3', '\u5348', '\u672a', '\u7533', '\u9149', '\u620c', '\u4ea5', ],

  /**
   * 天干地支之地支速查表<=>生肖
   * @Array Of Property
   * @trans["鼠","牛","虎","兔","龙","蛇","马","羊","猴","鸡","狗","猪"]
   * @return Cn string
   */
  Animals: ['\u9f20', '\u725b', '\u864e', '\u5154', '\u9f99', '\u86c7', '\u9a6c', '\u7f8a', '\u7334', '\u9e21', '\u72d7', '\u732a', ],

  /**
   * 阳历节日
   */
  festival: {
    '1-1': {
      title: '元旦节'
    },
    '2-14': {
      title: '情人节'
    },
    '5-1': {
      title: '劳动节'
    },
    '5-4': {
      title: '青年节'
    },
    '6-1': {
      title: '儿童节'
    },
    '9-10': {
      title: '教师节'
    },
    '10-1': {
      title: '国庆节'
    },
    '12-25': {
      title: '圣诞节'
    },

    '3-8': {
      title: '妇女节'
    },
    '3-12': {
      title: '植树节'
    },
    '4-1': {
      title: '愚人节'
    },
    '5-12': {
      title: '护士节'
    },
    '7-1': {
      title: '建党节'
    },
    '8-1': {
      title: '建军节'
    },
    '12-24': {
      title: '平安夜'
    },
  },

  /**
   * 农历节日
   */
  lfestival: {
    '12-30': {
      title: '除夕'
    },
    '1-1': {
      title: '春节'
    },
    '1-15': {
      title: '元宵节'
    },
    '5-5': {
      title: '端午节'
    },
    '8-15': {
      title: '中秋节'
    },
    '9-9': {
      title: '重阳节'
    },
    '7-7': {
      title: '七夕'
    },
  },

  /**
   * 返回默认定义的阳历节日
   */
  getFestival() {
    return this.festival
  },

  /**
   * 返回默认定义的内容里节日
   */
  getLunarFestival(y, m, d) {
    if (m == 12 && d == 29) {
      if (this.lunar2solar(y, m, 30) == -1) {
        delete this.lfestival['12-30']
        this.lfestival['12-29'] = {
          title: '除夕'
        }
      } else {
        delete this.lfestival['12-29']
        this.lfestival['12-30'] = {
          title: '除夕'
        }
      }
      //console.log(y, m, d, this.lunar2solar(y, m, 30));
    }
    return this.lfestival
  },

  /**
   *
   * @param {Object} 按照festival的格式输入数据,设置阳历节日
   */
  setFestival(param = {}) {
    this.festival = param
  },

  /**
   *
   * @param {Object} 按照lfestival的格式输入数据,设置农历节日
   */
  setLunarFestival(param = {}) {
    this.lfestival = param
  },

  /**
   * 24节气速查表
   * @Array Of Property
   * @trans["小寒","大寒","立春","雨水","惊蛰","春分","清明","谷雨","立夏","小满","芒种","夏至","小暑","大暑","立秋","处暑","白露","秋分","寒露","霜降","立冬","小雪","大雪","冬至"]
   * @return Cn string
   */
  solarTerm: ['\u5c0f\u5bd2', '\u5927\u5bd2', '\u7acb\u6625', '\u96e8\u6c34', '\u60ca\u86f0', '\u6625\u5206', '\u6e05\u660e', '\u8c37\u96e8', '\u7acb\u590f', '\u5c0f\u6ee1', '\u8292\u79cd', '\u590f\u81f3', '\u5c0f\u6691', '\u5927\u6691', '\u7acb\u79cb', '\u5904\u6691', '\u767d\u9732', '\u79cb\u5206', '\u5bd2\u9732', '\u971c\u964d', '\u7acb\u51ac', '\u5c0f\u96ea', '\u5927\u96ea', '\u51ac\u81f3', ],

  /**
   * 1900-2100各年的24节气日期速查表
   * @Array Of Property
   * @return 0x string For splice
   */
  sTermInfo: ['9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf97c3598082c95f8c965cc920f', '97bd0b06bdb0722c965ce1cfcc920f', 'b027097bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f', '97bd0b06bdb0722c965ce1cfcc920f', 'b027097bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f', '97bd0b06bdb0722c965ce1cfcc920f', 'b027097bd097c36b0b6fc9274c91aa', '9778397bd19801ec9210c965cc920e', '97b6b97bd19801ec95f8c965cc920f', '97bd09801d98082c95f8e1cfcc920f', '97bd097bd097c36b0b6fc9210c8dc2', '9778397bd197c36c9210c9274c91aa', '97b6b97bd19801ec95f8c965cc920e', '97bd09801d98082c95f8e1cfcc920f', '97bd097bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec95f8c965cc920e', '97bcf97c3598082c95f8e1cfcc920f', '97bd097bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf97c3598082c95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf97c3598082c95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f', '97bd097bd07f595b0b6fc920fb0722', '9778397bd097c36b0b6fc9210c8dc2', '9778397bd19801ec9210c9274c920e', '97b6b97bd19801ec95f8c965cc920f', '97bd07f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c920e', '97b6b97bd19801ec95f8c965cc920f', '97bd07f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bd07f1487f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf7f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf7f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf7f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf7f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c9274c920e', '97bcf7f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9210c91aa', '97b6b97bd197c36c9210c9274c920e', '97bcf7f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c920e', '97b6b7f0e47f531b0723b0b6fb0722', '7f0e37f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2', '9778397bd097c36b0b70c9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', '7f0e37f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc9210c8dc2', '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', '7f0e27f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0787b0721', '7f0e27f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9210c91aa', '97b6b7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9210c8dc2', '977837f0e37f149b0723b0787b0721', '7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f5307f595b0b0bc920fb0722', '7f0e397bd097c35b0b6fc9210c8dc2', '977837f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e37f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc9210c8dc2', '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14998082b0723b06bd', '7f07e7f0e37f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f1487f595b0b0bb0b6fb0722', '7f0e37f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f1487f531b0b0bb0b6fb0722', '7f0e37f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e37f1487f531b0b0bb0b6fb0722', '7f0e37f0e37f14898082b072297c35', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e37f0e37f14898082b072297c35', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f149b0723b0787b0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14998082b0723b06bd', '7f07e7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722', '7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14998082b0723b06bd', '7f07e7f0e37f14998083b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722', '7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14898082b0723b02d5', '7f07e7f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0722', '7f0e36665b66aa89801e9808297c35', '665f67f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0722', '7f0e36665b66a449801e9808297c35', '665f67f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e36665b66a449801e9808297c35', '665f67f0e37f14898082b072297c35', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e26665b66a449801e9808297c35', '665f67f0e37f1489801eb072297c35', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', ],

  /**
   * 数字转中文速查表
   * @Array Of Property
   * @trans ['日','一','二','三','四','五','六','七','八','九','十']
   * @return Cn string
   */
  nStr1: ['\u65e5', '\u4e00', '\u4e8c', '\u4e09', '\u56db', '\u4e94', '\u516d', '\u4e03', '\u516b', '\u4e5d', '\u5341', ],

  /**
   * 日期转农历称呼速查表
   * @Array Of Property
   * @trans ['初','十','廿','卅']
   * @return Cn string
   */
  nStr2: ['\u521d', '\u5341', '\u5eff', '\u5345'],

  /**
   * 月份转农历称呼速查表
   * @Array Of Property
   * @trans ['正','一','二','三','四','五','六','七','八','九','十','冬','腊']
   * @return Cn string
   */
  nStr3: ['\u6b63', '\u4e8c', '\u4e09', '\u56db', '\u4e94', '\u516d', '\u4e03', '\u516b', '\u4e5d', '\u5341', '\u51ac', '\u814a', ],

  /**
   * 返回农历y年一整年的总天数
   * @param lunar Year
   * @return Number
   * @eg:var count = calendar.lYearDays(1987) ;//count=387
   */
  lYearDays: function (y) {
    var i,
      sum = 348
    for (i = 0x8000; i > 0x8; i >>= 1) {
      sum += this.lunarInfo[y - 1900] & i ? 1 : 0
    }
    return sum + this.leapDays(y)
  },

  /**
   * 返回农历y年闰月是哪个月;若y年没有闰月 则返回0
   * @param lunar Year
   * @return Number (0-12)
   * @eg:var leapMonth = calendar.leapMonth(1987) ;//leapMonth=6
   */
  leapMonth: function (y) {
    //闰字编码 \u95f0
    return this.lunarInfo[y - 1900] & 0xf
  },

  /**
   * 返回农历y年闰月的天数 若该年没有闰月则返回0
   * @param lunar Year
   * @return Number (0、29、30)
   * @eg:var leapMonthDay = calendar.leapDays(1987) ;//leapMonthDay=29
   */
  leapDays: function (y) {
    if (this.leapMonth(y)) {
      return this.lunarInfo[y - 1900] & 0x10000 ? 30 : 29
    }
    return 0
  },

  /**
   * 返回农历y年m月(非闰月)的总天数,计算m为闰月时的天数请使用leapDays方法
   * @param lunar Year
   * @return Number (-1、29、30)
   * @eg:var MonthDay = calendar.monthDays(1987,9) ;//MonthDay=29
   */
  monthDays: function (y, m) {
    if (m > 12 || m < 1) {
      return -1
    } //月份参数从1至12,参数错误返回-1
    return this.lunarInfo[y - 1900] & (0x10000 >> m) ? 30 : 29
  },

  /**
   * 返回公历(!)y年m月的天数
   * @param solar Year
   * @return Number (-1、28、29、30、31)
   * @eg:var solarMonthDay = calendar.leapDays(1987) ;//solarMonthDay=30
   */
  solarDays: function (y, m) {
    if (m > 12 || m < 1) {
      return -1
    } //若参数错误 返回-1
    var ms = m - 1
    if (ms == 1) {
      //2月份的闰平规律测算后确认返回28或29
      return (y % 4 == 0 && y % 100 != 0) || y % 400 == 0 ? 29 : 28
    } else {
      return this.solarMonth[ms]
    }
  },

  /**
   * 农历年份转换为干支纪年
   * @param  lYear 农历年的年份数
   * @return Cn string
   */
  toGanZhiYear: function (lYear) {
    var ganKey = (lYear - 3) % 10
    var zhiKey = (lYear - 3) % 12
    if (ganKey == 0) ganKey = 10 //如果余数为0则为最后一个天干
    if (zhiKey == 0) zhiKey = 12 //如果余数为0则为最后一个地支
    return this.Gan[ganKey - 1] + this.Zhi[zhiKey - 1]
  },

  /**
   * 公历月、日判断所属星座
   * @param  cMonth [description]
   * @param  cDay [description]
   * @return Cn string
   */
  toAstro: function (cMonth, cDay) {
    var s =
      '\u9b54\u7faf\u6c34\u74f6\u53cc\u9c7c\u767d\u7f8a\u91d1\u725b\u53cc\u5b50\u5de8\u87f9\u72ee\u5b50\u5904\u5973\u5929\u79e4\u5929\u874e\u5c04\u624b\u9b54\u7faf'
    var arr = [20, 19, 21, 21, 21, 22, 23, 23, 23, 23, 22, 22]
    return s.substr(cMonth * 2 - (cDay < arr[cMonth - 1] ? 2 : 0), 2) + '\u5ea7' //座
  },

  /**
   * 传入offset偏移量返回干支
   * @param offset 相对甲子的偏移量
   * @return Cn string
   */
  toGanZhi: function (offset) {
    return this.Gan[offset % 10] + this.Zhi[offset % 12]
  },

  /**
   * 传入公历(!)y年获得该年第n个节气的公历日期
   * @param y公历年(1900-2100);n二十四节气中的第几个节气(1~24);从n=1(小寒)算起
   * @return day Number
   * @eg:var _24 = calendar.getTerm(1987,3) ;//_24=4;意即1987年2月4日立春
   */
  getTerm: function (y, n) {
    if (y < 1900 || y > 2100) {
      return -1
    }
    if (n < 1 || n > 24) {
      return -1
    }
    var _table = this.sTermInfo[y - 1900]
    var _info = [
      parseInt('0x' + _table.substr(0, 5)).toString(),
      parseInt('0x' + _table.substr(5, 5)).toString(),
      parseInt('0x' + _table.substr(10, 5)).toString(),
      parseInt('0x' + _table.substr(15, 5)).toString(),
      parseInt('0x' + _table.substr(20, 5)).toString(),
      parseInt('0x' + _table.substr(25, 5)).toString(),
    ]
    var _calday = [
      _info[0].substr(0, 1),
      _info[0].substr(1, 2),
      _info[0].substr(3, 1),
      _info[0].substr(4, 2),

      _info[1].substr(0, 1),
      _info[1].substr(1, 2),
      _info[1].substr(3, 1),
      _info[1].substr(4, 2),

      _info[2].substr(0, 1),
      _info[2].substr(1, 2),
      _info[2].substr(3, 1),
      _info[2].substr(4, 2),

      _info[3].substr(0, 1),
      _info[3].substr(1, 2),
      _info[3].substr(3, 1),
      _info[3].substr(4, 2),

      _info[4].substr(0, 1),
      _info[4].substr(1, 2),
      _info[4].substr(3, 1),
      _info[4].substr(4, 2),

      _info[5].substr(0, 1),
      _info[5].substr(1, 2),
      _info[5].substr(3, 1),
      _info[5].substr(4, 2),
    ]
    return parseInt(_calday[n - 1])
  },

  /**
   * 传入农历数字月份返回汉语通俗表示法
   * @param lunar month
   * @return Cn string
   * @eg:var cnMonth = calendar.toChinaMonth(12) ;//cnMonth='腊月'
   */
  toChinaMonth: function (m) {
    // 月 => \u6708
    if (m > 12 || m < 1) {
      return -1
    } //若参数错误 返回-1
    var s = this.nStr3[m - 1]
    s += '\u6708' //加上月字
    return s
  },

  /**
   * 传入农历日期数字返回汉字表示法
   * @param lunar day
   * @return Cn string
   * @eg:var cnDay = calendar.toChinaDay(21) ;//cnMonth='廿一'
   */
  toChinaDay: function (d) {
    //日 => \u65e5
    var s
    switch (d) {
      case 10:
        s = '\u521d\u5341'
        break
      case 20:
        s = '\u4e8c\u5341'
        break
        break
      case 30:
        s = '\u4e09\u5341'
        break
        break
      default:
        s = this.nStr2[Math.floor(d / 10)]
        s += this.nStr1[d % 10]
    }
    return s
  },

  /**
   * 年份转生肖[!仅能大致转换] => 精确划分生肖分界线是“立春”
   * @param y year
   * @return Cn string
   * @eg:var animal = calendar.getAnimal(1987) ;//animal='兔'
   */
  getAnimal: function (y) {
    return this.Animals[(y - 4) % 12]
  },

  /**
   * 传入阳历年月日获得详细的公历、农历object信息 <=>JSON
   * @param y  solar year
   * @param m  solar month
   * @param d  solar day
   * @return JSON object
   * @eg:console.log(calendar.solar2lunar(1987,11,01));
   */
  solar2lunar: function (y, m, d) {
    //console.log(this.initHoliday());
    let {
      workday,
      holiday
    } = this.initHoliday()
    //参数区间1900.1.31~2100.12.31
    y = parseInt(y)
    m = parseInt(m)
    d = parseInt(d)
    //年份限定、上限
    if (y < 1900 || y > 2100) {
      return -1 // undefined转换为数字变为NaN
    }
    //公历传参最下限
    if (y == 1900 && m == 1 && d < 31) {
      return -1
    }
    //未传参  获得当天
    if (!y) {
      var objDate = new Date()
    } else {
      var objDate = new Date(y, parseInt(m) - 1, d)
    }
    var i,
      leap = 0,
      temp = 0
    //修正ymd参数
    var y = objDate.getFullYear(),
      m = objDate.getMonth() + 1,
      d = objDate.getDate()
    var offset =
      (Date.UTC(objDate.getFullYear(), objDate.getMonth(), objDate.getDate()) -
        Date.UTC(1900, 0, 31)) /
      86400000
    for (i = 1900; i < 2101 && offset > 0; i++) {
      temp = this.lYearDays(i)
      offset -= temp
    }
    if (offset < 0) {
      offset += temp
      i--
    }

    //是否今天
    var isTodayObj = new Date(),
      isToday = false
    if (
      isTodayObj.getFullYear() == y &&
      isTodayObj.getMonth() + 1 == m &&
      isTodayObj.getDate() == d
    ) {
      isToday = true
    }
    //星期几
    var nWeek = objDate.getDay(),
      cWeek = this.nStr1[nWeek]
    //数字表示周几顺应天朝周一开始的惯例
    if (nWeek == 0) {
      nWeek = 7
    }
    //农历年
    var year = i
    var leap = this.leapMonth(i) //闰哪个月
    var isLeap = false

    //效验闰月
    for (i = 1; i < 13 && offset > 0; i++) {
      //闰月
      if (leap > 0 && i == leap + 1 && isLeap == false) {
        --i
        isLeap = true
        temp = this.leapDays(year) //计算农历闰月天数
      } else {
        temp = this.monthDays(year, i) //计算农历普通月天数
      }
      //解除闰月
      if (isLeap == true && i == leap + 1) {
        isLeap = false
      }
      offset -= temp
    }
    // 闰月导致数组下标重叠取反
    if (offset == 0 && leap > 0 && i == leap + 1) {
      if (isLeap) {
        isLeap = false
      } else {
        isLeap = true
          --i
      }
    }
    if (offset < 0) {
      offset += temp
        --i
    }
    //农历月
    var month = i
    //农历日
    var day = offset + 1
    //天干地支处理
    var sm = m - 1
    var gzY = this.toGanZhiYear(year)

    // 当月的两个节气
    // bugfix-2017-7-24 11:03:38 use lunar Year Param `y` Not `year`
    var firstNode = this.getTerm(y, m * 2 - 1) //返回当月「节」为几日开始
    var secondNode = this.getTerm(y, m * 2) //返回当月「节」为几日开始

    // 依据12节气修正干支月
    var gzM = this.toGanZhi((y - 1900) * 12 + m + 11)
    if (d >= firstNode) {
      gzM = this.toGanZhi((y - 1900) * 12 + m + 12)
    }

    //传入的日期的节气与否
    var isTerm = false
    var Term = null
    if (firstNode == d) {
      isTerm = true
      Term = this.solarTerm[m * 2 - 2]
    }
    if (secondNode == d) {
      isTerm = true
      Term = this.solarTerm[m * 2 - 1]
    }
    //日柱 当月一日与 1900/1/1 相差天数
    var dayCyclical = Date.UTC(y, sm, 1, 0, 0, 0, 0) / 86400000 + 25567 + 10
    var gzD = this.toGanZhi(dayCyclical + d - 1)
    //该日期所属的星座
    var astro = this.toAstro(m, d)

    var solarDate = y + '-' + (m + '').padStart(2, 0) + '-' + (d + '').padStart(2, 0)
    var lunarDate = year + '-' + month + '-' + day

    var festival = this.festival
    var lfestival = this.getLunarFestival(year, month, day)

    var festivalDate = m + '-' + d
    var lunarFestivalDate = month + '-' + day

    return {
      isWork: workday.includes(solarDate),
      isHoliday: holiday.includes(solarDate),
      date: solarDate,
      lunarDate: lunarDate,
      festival: festival[festivalDate] ? festival[festivalDate].title : null,
      lunarFestival: lfestival[lunarFestivalDate] ?
        lfestival[lunarFestivalDate].title : null,
      lYear: year,
      lMonth: month,
      lDay: day,
      Animal: this.getAnimal(year),
      IMonthCn: (isLeap ? '\u95f0' : '') + this.toChinaMonth(month),
      IDayCn: this.toChinaDay(day),
      cYear: y,
      cMonth: m,
      cDay: d,
      gzYear: gzY,
      gzMonth: gzM,
      gzDay: gzD,
      isToday: isToday,
      isLeap: isLeap,
      nWeek: nWeek,
      ncWeek: '\u661f\u671f' + cWeek,
      isTerm: isTerm,
      Term: Term,
      astro: astro,
    }
  },

  /**
   * 传入农历年月日以及传入的月份是否闰月获得详细的公历、农历object信息 <=>JSON
   * @param y  lunar year
   * @param m  lunar month
   * @param d  lunar day
   * @param isLeapMonth  lunar month is leap or not.[如果是农历闰月第四个参数赋值true即可]
   * @return JSON object
   * @eg:console.log(calendar.lunar2solar(1987,9,10));
   */
  lunar2solar: function (y, m, d, isLeapMonth) {
    //参数区间1900.1.31~2100.12.1
    y = parseInt(y)
    m = parseInt(m)
    d = parseInt(d)
    var isLeapMonth = !!isLeapMonth
    var leapOffset = 0
    var leapMonth = this.leapMonth(y)
    var leapDay = this.leapDays(y)
    if (isLeapMonth && leapMonth != m) {
      return -1
    } //传参要求计算该闰月公历 但该年得出的闰月与传参的月份并不同
    if ((y == 2100 && m == 12 && d > 1) || (y == 1900 && m == 1 && d < 31)) {
      return -1
    } //超出了最大极限值
    var day = this.monthDays(y, m)
    var _day = day
    //bugFix 2016-9-25
    //if month is leap, _day use leapDays method
    if (isLeapMonth) {
      _day = this.leapDays(y, m)
    }
    if (y < 1900 || y > 2100 || d > _day) {
      return -1
    } //参数合法性效验

    //计算农历的时间差
    var offset = 0
    for (var i = 1900; i < y; i++) {
      offset += this.lYearDays(i)
    }
    var leap = 0,
      isAdd = false
    for (var i = 1; i < m; i++) {
      leap = this.leapMonth(y)
      if (!isAdd) {
        //处理闰月
        if (leap <= i && leap > 0) {
          offset += this.leapDays(y)
          isAdd = true
        }
      }
      offset += this.monthDays(y, i)
    }
    //转换闰月农历 需补充该年闰月的前一个月的时差
    if (isLeapMonth) {
      offset += day
    }
    //1900年农历正月一日的公历时间为1900年1月30日0时0分0秒(该时间也是本农历的最开始起始点)
    var stmap = Date.UTC(1900, 1, 30, 0, 0, 0)
    var calObj = new Date((offset + d - 31) * 86400000 + stmap)
    var cY = calObj.getUTCFullYear()
    var cM = calObj.getUTCMonth() + 1
    var cD = calObj.getUTCDate()
    return `${cY}${cM}${cD}`
    // return this.solar2lunar(cY, cM, cD)
  },
  // 初始化节假日
  initHoliday: function () {
    let workday = []
    let holiday = []
    window.Holiday.HolidayConfig.forEach(yearItem => {
      yearItem.Work.forEach(item => {
        workday.push(`${yearItem.Year}-${(item + '').substring(0,2)}-${(item + '').substring(2,4)}`)
      })
      yearItem.Holiday.forEach(item => {
        holiday.push(`${yearItem.Year}-${(item + '').substring(0,2)}-${(item + '').substring(2,4)}`)
      })
    })
    return {
      workday,
      holiday
    }
  }
}
window.Holiday = {
  "HolidayConfig": [
    {
      "Year": 2022,
      "Work": ["0129", "0130", "0402", "0424", "0507", "1008", "1009"],
      "Holiday": ["0103", "0131", "0201", "0202", "0203", "0204", "0404", "0405", "0502", "0503", "0504", "0603", "0912", "1003", "1004", "1005", "1006", "1007", "1231"]
    },
    {
      "Year": 2023,
      "Work": [],
      "Holiday": ["0102", "0123", "0124", "0125", "0126", "0127"]
    }
  ]
};
  1. 修改date-picker>src>basic>date-table中数据;
<template>
  <table
    cellspacing="0"
    cellpadding="0"
    class="el-date-table"
    @click="handleClick"
    @mousemove="handleMouseMove"
    :class="{ 'is-week-mode': selectionMode === 'week' }"
  >
    <tbody>
      <tr>
        <th v-if="showWeekNumber">{{ t("el.datepicker.week") }}</th>
        <th v-for="(week, key) in WEEKS" :key="key">
          {{ t("el.datepicker.weeks." + week) }}
        </th>
      </tr>
      <tr
        class="el-date-table__row"
        v-for="(row, key) in rows"
        :class="{ current: isWeekActive(row[1]) }"
        :key="key"
      >
        <td v-for="(cell, key) in row" :class="getCellClasses(cell)" :key="key">
          <div
            :class="{
              'is-weekend': [6, 7].includes(cell.lunar.nWeek),
              'is-work': cell.lunar.isWork,
              'is-holiday': cell.lunar.isHoliday,
            }"
          >
            <span>
              {{ cell.text }}
            </span>
            <section style="position: relative; top: 14px">
              {{
                cell.lunar.lunarFestival
                  ? cell.lunar.lunarFestival
                  : cell.lunar.festival
                  ? cell.lunar.festival
                  : cell.lunar.IDayCn == "初一"
                  ? cell.lunar.IMonthCn
                  : cell.lunar.IDayCn
              }}
            </section>
          </div>
        </td>
      </tr>
    </tbody>
  </table>
</template>

<script>
import {
  getFirstDayOfMonth,
  getDayCountOfMonth,
  getWeekNumber,
  getStartDateOfMonth,
  prevDate,
  nextDate,
  isDate,
  clearTime as _clearTime,
} from "element-ui/src/utils/date-util";
import Locale from "element-ui/src/mixins/locale";
import {
  arrayFindIndex,
  arrayFind,
  coerceTruthyValueToArray,
} from "element-ui/src/utils/util";
import calendar from "@/utils/date";

const WEEKS = ["sun", "mon", "tue", "wed", "thu", "fri", "sat"];
const getDateTimestamp = function (time) {
  if (typeof time === "number" || typeof time === "string") {
    return _clearTime(new Date(time)).getTime();
  } else if (time instanceof Date) {
    return _clearTime(time).getTime();
  } else {
    return NaN;
  }
};

// remove the first element that satisfies `pred` from arr
// return a new array if modification occurs
// return the original array otherwise
const removeFromArray = function (arr, pred) {
  const idx =
    typeof pred === "function" ? arrayFindIndex(arr, pred) : arr.indexOf(pred);
  return idx >= 0 ? [...arr.slice(0, idx), ...arr.slice(idx + 1)] : arr;
};

export default {
  mixins: [Locale],

  props: {
    firstDayOfWeek: {
      default: 7,
      type: Number,
      validator: (val) => val >= 1 && val <= 7,
    },

    value: {},

    defaultValue: {
      validator(val) {
        // either: null, valid Date object, Array of valid Date objects
        return (
          val === null ||
          isDate(val) ||
          (Array.isArray(val) && val.every(isDate))
        );
      },
    },

    date: {},

    selectionMode: {
      default: "day",
    },

    showWeekNumber: {
      type: Boolean,
      default: false,
    },

    disabledDate: {},

    cellClassName: {},

    minDate: {},

    maxDate: {},

    rangeState: {
      default() {
        return {
          endDate: null,
          selecting: false,
        };
      },
    },
  },

  computed: {
    offsetDay() {
      const week = this.firstDayOfWeek;
      // 周日为界限,左右偏移的天数,3217654 例如周一就是 -1,目的是调整前两行日期的位置
      return week > 3 ? 7 - week : -week;
    },

    WEEKS() {
      const week = this.firstDayOfWeek;
      return WEEKS.concat(WEEKS).slice(week, week + 7);
    },

    year() {
      return this.date.getFullYear();
    },

    month() {
      return this.date.getMonth();
    },

    startDate() {
      return getStartDateOfMonth(this.year, this.month);
    },

    rows() {
      // TODO: refactory rows / getCellClasses
      const date = new Date(this.year, this.month, 1);
      let day = getFirstDayOfMonth(date); // day of first day
      const dateCountOfMonth = getDayCountOfMonth(
        date.getFullYear(),
        date.getMonth()
      );
      const dateCountOfLastMonth = getDayCountOfMonth(
        date.getFullYear(),
        date.getMonth() === 0 ? 11 : date.getMonth() - 1
      );

      day = day === 0 ? 7 : day;

      const offset = this.offsetDay;
      const rows = this.tableRows;
      let count = 1;

      const startDate = this.startDate;
      const disabledDate = this.disabledDate;
      const cellClassName = this.cellClassName;
      const selectedDate =
        this.selectionMode === "dates"
          ? coerceTruthyValueToArray(this.value)
          : [];
      const now = getDateTimestamp(new Date());

      for (let i = 0; i < 6; i++) {
        const row = rows[i];

        if (this.showWeekNumber) {
          if (!row[0]) {
            row[0] = {
              type: "week",
              text: getWeekNumber(nextDate(startDate, i * 7 + 1)),
              lunar: calendar.solar2lunar(
                this.year,
                this.month,
                nextDate(startDate, i * 7 + 1)
              ),
            };
          }
        }

        for (let j = 0; j < 7; j++) {
          let cell = row[this.showWeekNumber ? j + 1 : j];
          if (!cell) {
            cell = {
              row: i,
              column: j,
              type: "normal",
              inRange: false,
              start: false,
              end: false,
            };
          }

          cell.type = "normal";

          const index = i * 7 + j;
          const time = nextDate(startDate, index - offset).getTime();
          cell.inRange =
            time >= getDateTimestamp(this.minDate) &&
            time <= getDateTimestamp(this.maxDate);
          cell.start = this.minDate && time === getDateTimestamp(this.minDate);
          cell.end = this.maxDate && time === getDateTimestamp(this.maxDate);
          const isToday = time === now;

          if (isToday) {
            cell.type = "today";
          }

          if (i >= 0 && i <= 1) {
            const numberOfDaysFromPreviousMonth =
              day + offset < 0 ? 7 + day + offset : day + offset;

            if (j + i * 7 >= numberOfDaysFromPreviousMonth) {
              cell.text = count++;
              //console.log(calendar.solar2lunar(this.year, this.month + 1, cell.text))
              cell.lunar = calendar.solar2lunar(
                this.year,
                this.month + 1,
                cell.text
              );
            } else {
              cell.text =
                dateCountOfLastMonth -
                (numberOfDaysFromPreviousMonth - (j % 7)) +
                1 +
                i * 7;
              cell.type = "prev-month";
              cell.lunar = calendar.solar2lunar(
                this.year,
                this.month,
                cell.text
              );
            }
          } else {
            if (count <= dateCountOfMonth) {
              cell.text = count++;
              cell.lunar = calendar.solar2lunar(
                this.year,
                this.month + 1,
                cell.text
              );
            } else {
              cell.text = count++ - dateCountOfMonth;
              cell.type = "next-month";
              cell.lunar = calendar.solar2lunar(
                this.year,
                this.month + 2,
                cell.text
              );
            }
          }

          const cellDate = new Date(time);
          cell.disabled =
            typeof disabledDate === "function" && disabledDate(cellDate);
          cell.selected = arrayFind(
            selectedDate,
            (date) => date.getTime() === cellDate.getTime()
          );
          cell.customClass =
            typeof cellClassName === "function" && cellClassName(cellDate);
          this.$set(row, this.showWeekNumber ? j + 1 : j, cell);
        }

        if (this.selectionMode === "week") {
          const start = this.showWeekNumber ? 1 : 0;
          const end = this.showWeekNumber ? 7 : 6;
          const isWeekActive = this.isWeekActive(row[start + 1]);

          row[start].inRange = isWeekActive;
          row[start].start = isWeekActive;
          row[end].inRange = isWeekActive;
          row[end].end = isWeekActive;
        }
      }

      return rows;
    },
  },

  watch: {
    "rangeState.endDate"(newVal) {
      this.markRange(this.minDate, newVal);
    },

    minDate(newVal, oldVal) {
      if (getDateTimestamp(newVal) !== getDateTimestamp(oldVal)) {
        this.markRange(this.minDate, this.maxDate);
      }
    },

    maxDate(newVal, oldVal) {
      if (getDateTimestamp(newVal) !== getDateTimestamp(oldVal)) {
        this.markRange(this.minDate, this.maxDate);
      }
    },
  },

  data() {
    return {
      tableRows: [[], [], [], [], [], []],
      lastRow: null,
      lastColumn: null,
    };
  },

  methods: {
    cellMatchesDate(cell, date) {
      const value = new Date(date);
      return (
        this.year === value.getFullYear() &&
        this.month === value.getMonth() &&
        Number(cell.text) === value.getDate()
      );
    },

    getCellClasses(cell) {
      const selectionMode = this.selectionMode;
      const defaultValue = this.defaultValue
        ? Array.isArray(this.defaultValue)
          ? this.defaultValue
          : [this.defaultValue]
        : [];

      const classes = [];
      if ((cell.type === "normal" || cell.type === "today") && !cell.disabled) {
        classes.push("available");
        if (cell.type === "today") {
          classes.push("today");
        }
      } else {
        classes.push(cell.type);
      }

      if (
        cell.type === "normal" &&
        defaultValue.some((date) => this.cellMatchesDate(cell, date))
      ) {
        classes.push("default");
      }

      if (
        selectionMode === "day" &&
        (cell.type === "normal" || cell.type === "today") &&
        this.cellMatchesDate(cell, this.value)
      ) {
        classes.push("current");
      }

      if (
        cell.inRange &&
        (cell.type === "normal" ||
          cell.type === "today" ||
          this.selectionMode === "week")
      ) {
        classes.push("in-range");

        if (cell.start) {
          classes.push("start-date");
        }

        if (cell.end) {
          classes.push("end-date");
        }
      }

      if (cell.disabled) {
        classes.push("disabled");
      }

      if (cell.selected) {
        classes.push("selected");
      }

      if (cell.customClass) {
        classes.push(cell.customClass);
      }

      return classes.join(" ");
    },

    getDateOfCell(row, column) {
      const offsetFromStart =
        row * 7 + (column - (this.showWeekNumber ? 1 : 0)) - this.offsetDay;
      return nextDate(this.startDate, offsetFromStart);
    },

    isWeekActive(cell) {
      if (this.selectionMode !== "week") return false;
      const newDate = new Date(this.year, this.month, 1);
      const year = newDate.getFullYear();
      const month = newDate.getMonth();

      if (cell.type === "prev-month") {
        newDate.setMonth(month === 0 ? 11 : month - 1);
        newDate.setFullYear(month === 0 ? year - 1 : year);
      }

      if (cell.type === "next-month") {
        newDate.setMonth(month === 11 ? 0 : month + 1);
        newDate.setFullYear(month === 11 ? year + 1 : year);
      }

      newDate.setDate(parseInt(cell.text, 10));

      if (isDate(this.value)) {
        const dayOffset =
          ((this.value.getDay() - this.firstDayOfWeek + 7) % 7) - 1;
        const weekDate = prevDate(this.value, dayOffset);
        return weekDate.getTime() === newDate.getTime();
      }
      return false;
    },

    markRange(minDate, maxDate) {
      minDate = getDateTimestamp(minDate);
      maxDate = getDateTimestamp(maxDate) || minDate;
      [minDate, maxDate] = [
        Math.min(minDate, maxDate),
        Math.max(minDate, maxDate),
      ];

      const startDate = this.startDate;
      const rows = this.rows;
      for (let i = 0, k = rows.length; i < k; i++) {
        const row = rows[i];
        for (let j = 0, l = row.length; j < l; j++) {
          if (this.showWeekNumber && j === 0) continue;

          const cell = row[j];
          const index = i * 7 + j + (this.showWeekNumber ? -1 : 0);
          const time = nextDate(startDate, index - this.offsetDay).getTime();

          cell.inRange = minDate && time >= minDate && time <= maxDate;
          cell.start = minDate && time === minDate;
          cell.end = maxDate && time === maxDate;
        }
      }
    },

    handleMouseMove(event) {
      if (!this.rangeState.selecting) return;

      let target = event.target;
      if (target.tagName === "SPAN") {
        target = target.parentNode.parentNode;
      }
      if (target.tagName === "DIV") {
        target = target.parentNode;
      }
      if (target.tagName !== "TD") return;

      const row = target.parentNode.rowIndex - 1;
      const column = target.cellIndex;

      // can not select disabled date
      if (this.rows[row][column].disabled) return;

      // only update rangeState when mouse moves to a new cell
      // this avoids frequent Date object creation and improves performance
      if (row !== this.lastRow || column !== this.lastColumn) {
        this.lastRow = row;
        this.lastColumn = column;
        this.$emit("changerange", {
          minDate: this.minDate,
          maxDate: this.maxDate,
          rangeState: {
            selecting: true,
            endDate: this.getDateOfCell(row, column),
          },
        });
      }
    },

    handleClick(event) {
      let target = event.target;
      if (target.tagName === "SPAN" || target.tagName == "SECTION") {
        target = target.parentNode.parentNode;
      }
      if (target.tagName === "DIV") {
        target = target.parentNode;
      }

      if (target.tagName !== "TD") return;

      const row = target.parentNode.rowIndex - 1;
      const column = this.selectionMode === "week" ? 1 : target.cellIndex;
      const cell = this.rows[row][column];

      if (cell.disabled || cell.type === "week") return;

      const newDate = this.getDateOfCell(row, column);

      if (this.selectionMode === "range") {
        if (!this.rangeState.selecting) {
          this.$emit("pick", { minDate: newDate, maxDate: null });
          this.rangeState.selecting = true;
        } else {
          if (newDate >= this.minDate) {
            this.$emit("pick", { minDate: this.minDate, maxDate: newDate });
          } else {
            this.$emit("pick", { minDate: newDate, maxDate: this.minDate });
          }
          this.rangeState.selecting = false;
        }
      } else if (this.selectionMode === "day") {
        this.$emit("pick", newDate);
      } else if (this.selectionMode === "week") {
        const weekNumber = getWeekNumber(newDate);
        const value = newDate.getFullYear() + "w" + weekNumber;
        this.$emit("pick", {
          year: newDate.getFullYear(),
          week: weekNumber,
          value: value,
          date: newDate,
        });
      } else if (this.selectionMode === "dates") {
        const value = this.value || [];
        const newValue = cell.selected
          ? removeFromArray(
              value,
              (date) => date.getTime() === newDate.getTime()
            )
          : [...value, newDate];
        this.$emit("pick", newValue);
      }
    },
  },
};
</script>
<style lang="scss">
$primary: #409eff;
.el-date-table td {
  height: 45px;
}
.el-date-table td span {
  z-index: 9;
}
.el-date-table td.start-date section,
.el-date-table td.end-date section {
  color: #333;
}
.el-date-table td.start-date span,
.el-date-table td.end-date span {
  color: #ffffff;
}
.el-date-table td div {
  height: 45px;
}
.available .is-weekend {
  //color: red !important;
  &:hover {
    color: $primary !important;
  }
}
.available .is-work {
  color: #606266 !important;
  &:hover {
    color: $primary !important;
  }
}
.el-date-table td.today {
  color: #409eff;
}
.available .is-holiday {
  //color: red !important;
  &:hover {
    color: $primary !important;
  }
}
.prev-month .is-weekend,
.next-month .is-weekend,
.prev-month .is-holiday,
.next-month .is-holiday {
  //color: #ef5f5f !important;
}
</style>

三、 扩展:节假日、周末标红

element ui 日期组件 默认显示当天 elementui日历插件_elementui_02

四、节假日和今天之前数据不可点击 

element ui 日期组件 默认显示当天 elementui日历插件_f5_03

<template>
  <div>
    <date-picker
      v-model="value1"
      type="date"
      :picker-options="{
        disabledDate,
        firstDayOfWeek: 1,
      }"
      placeholder="选择日期"
    >
    </date-picker>
  </div>
</template>

<script>
import DatePicker from "@/components/datePicker/index";
export default {
  components: {
    DatePicker,
  },
  data() {
    return {
      value1: "",
      finishTime: "2100-01-01 00:00:00", // 限制到某月某日以后不能被选择
      holidays: [], // 后端返回数据
    };
  },
  created() {
    window.Holiday.HolidayConfig.forEach((yearItem) => {
      yearItem.Holiday.forEach((item) => {
        this.holidays.push(
          `${yearItem.Year}-${(item + "").substring(0, 2)}-${(
            item + ""
          ).substring(2, 4)}`
        );
      });
    });
  },
  methods: {
    // 定义限制的方法
    disabledDate(time) {
      // 设置不能选择今天之前的时间
      let beforeTime = new Date();
      beforeTime.setTime(beforeTime.getTime() - 24 * 60 * 60 * 1000);
      // 设置不能选择结束的时间,并把字符串转日期
      let finishTime = Date.parse(this.finishTime.replace(/-/g, "-"));
      return (
        time.getTime() < beforeTime ||
        time.getTime() > finishTime ||
        time.getDay() == 6 ||
        time.getDay() == 0 ||
        this.holidays.indexOf(this.setyyyyMMdd(time.getTime()).slice(0, 10)) !=
          -1
      );
    },
    // 设置时间格式为yyyy-mm-dd方法
    setyyyyMMdd(time) {
      let date = new Date(time);
      var y = date.getFullYear();
      var m = date.getMonth() + 1;
      m = m < 10 ? "0" + m : m;
      var d = date.getDate();
      d = d < 10 ? "0" + d : d;
      var h = date.getHours();
      h = h < 10 ? "0" + h : h;
      var minute = date.getMinutes();
      minute = minute < 10 ? "0" + minute : minute;
      var second = date.getSeconds();
      second = second < 10 ? "0" + second : second;
      return y + "-" + m + "-" + d + " " + h + ":" + minute + ":" + second;
    },
  },
};
</script>

<style>
</style>