前言:首先我看到这个需求的时候是懵逼的,这是提出的啥J8需求? 但是想到用户就是上帝,我只是21世纪的高级农民工,马上平复心情回到现实开始动手。

逻辑步骤:
1,选出前七天的时间并且过滤掉节假日与周六末,并记录过滤掉了几天,然后继续往前补几天。
2,比如昨天跟前天都是节假日,往前补天的时候会出现补到非节假日的一天然后有补天日期重复的情况,所以需要拿到日期 然后再内部过滤一下重复,如果重复继续往前补。

先放实现的功能图:

我当天是2022年2月9号,所以可选值为2月8号,2月7号,1月28,1月27,1月26,1月25,1月24(因为中间的时间有的是周末或者节假日)

element 日历加样式 elementui节假日日历_element 日历加样式


element 日历加样式 elementui节假日日历_element 日历加样式_02


用到的节假日跟周六周末的数据写死放结尾了,正常写项目的话可以直接让后端返回自己想要的数据格式。

接下来是硬货代码:

<el-form-item label="日期" prop="endTime">
          <el-date-picker
            v-model="formData.endTime"
            format="yyyy-MM-dd"
            value-format="yyyy-MM-dd"
            :style="{ width: '100%' }"
            placeholder="请选择日期"
            clearable
            :picker-options="pickerOptions"
          ></el-date-picker>
      </el-form-item>

这里我还写了个自定义的form验证(我也真傻逼,可忽略不计)

export default {
  data() {
   	rules: {
	  endTime: [
          {
            required: true,
            message: "请选择最后工作日",
            trigger: "change"
          },
          {
            validator: (rule, value, callback) => {
              if (!value) {
                callback(new Error("请选择最后工作日"));
                return false;
              }

              if (this.filterDate.includes(this.formatDate(value) * 1)) {
                callback(new Error("不可选择节假日日期!"));
                return false;
              } else {
                callback();
              }
            }
          }
        ],
	},
	  // 这里的filterDate是2022年的节假日与周六末,这个数据太长了 放结尾了,兄弟们复制的时候不要忘记把数据赋值进来!
	  filterDate: [],
	  // 日期选择器的配置禁用选项
      pickerOptions: {},
      // 前七天日期list
      dates: [],
      // 过滤好的七天日期
      newDate: []
   },
    created() {
       // 往前推7天时间
	    var num = 0;
	     // 第一次数据为空肯定是7
	    let number = this.dates.lentgh || 7;
	    // 拿到前七天时间
	    for (var i = 0; i < number; i++) {
	      num++;
	      this.dates.push(this.formatDate(new Date() - num * 24 * 3600 * 1000));
	    }
		
		// 拿到七天的时间  然后挨个自调用的方法中
	    this.dates.map(m => {
	      this.getDateList(m);
	    });
	
	     // 这里的逻辑是等上一步的this.getDateList方法执行完毕以后拿到的最新的日期组并且格式化时间用来匹配element的disabledDate内部不可选方法时间戳
	     // newDate拿到的是向前推七天的工作日时间
	      let ar = this.newDate.map(m => {
	      let y = m.split("")[0] + m.split("")[1] + m.split("")[2] + m.split("")[3];
	      let month = m.split("")[4] + m.split("")[5];
	      let d = m.split("")[6] + m.split("")[7];
	      /* 转为标准的时间为年-月-日 时:分:秒 用来去比较element的内部时间 */
	      return this.formatDateCopy(y + "-" + month + "-" + d);
	    });
	
	    /**肯定是7个数组 所以直接写死数组长度 */
	    this.pickerOptions = {
	      disabledDate(time) {
	        return (
	          time.getTime() !== new Date(ar[0]).getTime() &&
	          time.getTime() !== new Date(ar[1]).getTime() &&
	          time.getTime() !== new Date(ar[2]).getTime() &&
	          time.getTime() !== new Date(ar[3]).getTime() &&
	          time.getTime() !== new Date(ar[4]).getTime() &&
	          time.getTime() !== new Date(ar[5]).getTime() &&
	          time.getTime() !== new Date(ar[6]).getTime()
	        );
	      }
	    };
	    /* 这里我写的比较傻逼,因为我已经快疯了手动赋值的,但是能实现就是好代码,又是记录代码的一天 */
	  },
	  
   methods: {
    getDateList(date) {
      var _this = this;

      /**节假日判断  */
      if (_this.filterDate.includes(date * 1)) {
        let y =
          date.split("")[0] +
          date.split("")[1] +
          date.split("")[2] +
          date.split("")[3];
        let month = date.split("")[4] + date.split("")[5];
        let d = date.split("")[6] + date.split("")[7];

        let time = _this.formatDate(
          new Date(_this.formatDateCopy(y + "-" + month + "-" + d)).getTime() -
            24 * 3600 * 1000
        );

        this.getDateList(time);
        return;
      }

      /**自身递归判断 */
      if (this.newDate.length > 0) {
        let y =
          date.split("")[0] +
          date.split("")[1] +
          date.split("")[2] +
          date.split("")[3];
        let month = date.split("")[4] + date.split("")[5];
        let d = date.split("")[6] + date.split("")[7];

        var time3 = _this.formatDate(
          new Date(_this.formatDateCopy(y + "-" + month + "-" + d)).getTime()
        );
        var time4 = _this.formatDate(
          new Date(_this.formatDateCopy(y + "-" + month + "-" + d)).getTime() -
            24 * 3600 * 1000
        );

        if (this.newDate.includes(time3)) {
          this.getDateList(time4);
          return;
        }
      }
	  /* 如果过了节假日判断与自身不重复的判断,就push到新的数组中并且去重 */
      this.newDate.push(date);
      this.newDate = this.set(this.newDate);
    },

     /* 去重 */
    set(ar) {
      return Array.from(new Set(ar));
    },

     /* 格式化时间为年-月-日 时:分:秒 用来去比较element的内部方法(必须加上00:00:00) ,因为element内部的方法日期计算是凌晨0点,所以需要手动添加 如果不加的话 时间就匹配不上了 */
    formatDateCopy(date) {
      var date = new Date(date);
      var year = date.getFullYear();
      var month = this.formatTen(date.getMonth() + 1);
      let d = this.formatTen(date.getDate());
      return year + "-" + month + "-" + d + " " + "00:00:00";
    },

     /* 格式化时间为年月日 用来匹配后端返回的filterDate数据 (怎么格式化看后端怎么返回数据格式)*/
    formatDate(date) {
      var date = new Date(date);
      var year = date.getFullYear();
      var month = this.formatTen(date.getMonth() + 1);
      let d = this.formatTen(date.getDate());
      return year + month + d;
    },

    // 补零
    formatTen(num) {
      return num > 9 ? num + "" : "0" + num;
    },
  }

最后不要忘记把filterDate的数据引入!!!

filterDate: [
        20220101,
        20220102,
        20220103,
        20220108,
        20220109,
        20220115,
        20220116,
        20220122,
        20220123,
        20220129,
        20220130,
        20220131,
        20220201,
        20220202,
        20220203,
        20220204,
        20220205,
        20220206,
        20220212,
        20220213,
        20220219,
        20220220,
        20220226,
        20220227,
        20220305,
        20220306,
        20220312,
        20220313,
        20220319,
        20220320,
        20220326,
        20220327,
        20220403,
        20220404,
        20220405,
        20220409,
        20220410,
        20220416,
        20220417,
        20220423,
        20220430,
        20220501,
        20220502,
        20220503,
        20220504,
        20220508,
        20220514,
        20220515,
        20220521,
        20220522,
        20220528,
        20220529,
        20220603,
        20220604,
        20220605,
        20220611,
        20220612,
        20220618,
        20220619,
        20220625,
        20220626,
        20220702,
        20220703,
        20220709,
        20220710,
        20220716,
        20220717,
        20220723,
        20220724,
        20220730,
        20220731,
        20220806,
        20220807,
        20220813,
        20220814,
        20220820,
        20220821,
        20220827,
        20220828,
        20220903,
        20220904,
        20220910,
        20220911,
        20220912,
        20220917,
        20220918,
        20220924,
        20220925,
        20221001,
        20221002,
        20221003,
        20221004,
        20221005,
        20221006,
        20221007,
        20221015,
        20221016,
        20221022,
        20221023,
        20221029,
        20221030,
        20221105,
        20221106,
        20221112,
        20221113,
        20221119,
        20221120,
        20221126,
        20221127,
        20221203,
        20221204,
        20221210,
        20221211,
        20221217,
        20221218,
        20221224,
        20221225,
        20221231
      ],