自定义日历范围

需要下moment包

javascript 复制代码
<template>
  <div>
    <el-button type="primary" @click="getDailyAllocation()">自定义日历</el-button>
    <el-dialog title="选择跳过日期" :visible.sync="dialogVisible" :close-on-click-modal="false" width="700px">
      <div class="date-list">
        <div class="date-items" v-for="(item) in week" :key="item">{{item}}</div>
        <div class="date-item" v-for="(item,index) in timeData" :key="index" :class="item.flag ? 'on' : '' ">
          <el-link @click="selectDay(item)" :underline="false" :disabled='array.includes(item.allocationDate)'>
            <div v-if="item.allocationDate">
              <div>{{item.allocationDate}}</div>
            </div>
          </el-link>
        </div>
      </div>

      <span slot="footer" class="dialog-footer">
        <div>
          <el-button @click="dialogVisible = false">取 消</el-button>
          <el-button @click="submit()">提 交</el-button>
        </div>
      </span>
    </el-dialog>
  </div>
</template>

<script>
import moment from 'moment'
export default {
  data () {
    return {
      time: [], // 用来高亮日期
      week: ['一', '二', '三', '四', '五', '六', '日'],
      array: [], // 补日历的数据
      dialogVisible: false,
      startDate: '2023-12-28', // 开始日期
      endDate: '2024-1-26', // 结束日期
      timeData: [] // 日历
    }
  },
  mounted () {
    this.generateDates()
  },
  methods: {
    // 根据开始日期和结束日期 生成日历数据
    generateDates () {
      const start = new Date(this.startDate);
      const end = new Date(this.endDate);
      const dates = [];

      while (start <= end) {
        const year = start.getFullYear();
        const month = String(start.getMonth() + 1).padStart(2, '0');
        const day = String(start.getDate()).padStart(2, '0');
        const shortDate = `${month}-${day}`;
        const weekDay = this.getWeekDay(start.getDay());

        dates.push({
          allocationDate: `${year}-${month}-${day}`,
          shortDate: shortDate,
          weekDay: weekDay,
          flag: false
        })

        start.setDate(start.getDate() + 1);
      }

      this.timeData = dates;
    },
    getWeekDay (dayIndex) {
      const daysOfWeek = ['SUNDAY', 'MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY', 'FRIDAY', 'SATURDAY']
      return daysOfWeek[dayIndex]
    },
    // 数据处理展示成日历
    async getDailyAllocation () {
      let startDate = moment(this.timeData[0].allocationDate)
      let endDate = null
      let week = moment(startDate).weekday()
      // week 为0 说明是周日
      if (week === 0) {
        week = 7
      }
      if (week > 1) {
        week = week - 1
        startDate = moment(startDate).subtract(week, 'days')
        endDate = moment(this.timeData[0].allocationDate)
        // 大于周一的数据都存储
        const arr = []
        // arr.push({ allocationDate: startDate.format('YYYY-MM-DD') })
        arr.push({ allocationDate: '' })
        while (startDate.add(1, 'days').isBefore(endDate)) {
          // 注意这里add方法处理后SDate对象已经改变。
          arr.push({ allocationDate: '' })
        }
        this.timeData = [...arr, ...this.timeData]
        // 拿到补的数据
        this.array = arr.map(item => item.allocationDate)
      }
      this.dialogVisible = true
    },
    // 选择日期
    async selectDay (item) {
      if (!this.timeData || !Array.isArray(this.timeData)) {
        console.error('timeData is not an array or undefined')
        return
      }
      if (!this.time || !Array.isArray(this.time)) {
        console.error('time is not an array or undefined')
        return
      }
      const tempSet = new Set(this.time)
      for (const item2 of this.timeData) {
        if (item.allocationDate === item2.allocationDate) {
          item.flag = !item.flag
        }
        if (item.flag) {
          tempSet.add(item.allocationDate)
        } else {
          tempSet.delete(item.allocationDate)
        }
      }
      this.time = Array.from(tempSet)
    },
    // 提交
    submit () {
      // 数据排列
      console.log(this.time.sort((item1, item2) => new Date(item1) - new Date(item2)))

    }
  }
}
</script>

<style lang="less" scoped>
.date-list {
  width: 100%;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  .date-item,
  .date-items {
    width: calc(100% / 7);
    text-align: center;
  }
  .date-items {
    line-height: 40px;
    height: 40px;
    background: #f5f7fa;
  }
  .date-item {
    height: 60px;
    cursor: pointer;
    border: 1px solid #e4e7ed;
    box-sizing: border-box;
    .el-link {
      width: 100%;
      height: 100%;
    }
  }
}
.on {
  background: #409eff;
  .el-link.el-link--default {
    color: #ffff;
  }
}
</style>
相关推荐
不简说21 小时前
JS 代码技巧 vol.8 — 20 个函数式编程实战,把 if/else 拍扁的骚操作
前端·javascript·面试
头茬韭菜21 小时前
4.9 SSRF 防护 — Web 工具的出站安全与私有 IP 拦截
前端·tcp/ip·安全
Cobyte21 小时前
模板 DSL 解析器中的状态机设计
前端·javascript·vue.js
颜酱21 小时前
# 02 | 搭骨架:用 LangGraph 编排 12 步工作流(思路)
前端·人工智能·后端
颜酱21 小时前
02 | 搭骨架:用 LangGraph 编排 12 步工作流
前端·人工智能·后端
刘卓航众创芯云服务部1 天前
Kimi K3复杂任务实测:我把团队最头疼的三个场景全跑了一遍
前端
软件开发技术深度爱好者1 天前
小学英语单词魔法学园HTML5实现
javascript·html5·英语学习
勉灬之1 天前
Next.js + Prisma 跨平台部署踩坑记
开发语言·javascript·ecmascript
cll_8692418911 天前
一个好看的Wordpress博客文字css样式
前端·css·ui
武子康1 天前
Shippy:确定性工具、会话级 Sandbox 与 Live-Data Eval(4 类收敛 + 7 步实现方案 + 6 类评测指标)
前端·人工智能·后端