【Vue+Element】实现日历任务展示

【Vue+Element】实现日历任务展示

效果图

在这里插入图片描述

代码

新建Calendar.vue

<template>
  <div>
    <!-- 日历头部 -->
    <div class="calendar-header">
      <div class="calendar-header-btn">
        <i class="el-icon-d-arrow-left" @click="changeDateForYear('pre')"></i>
        <i class="el-icon-arrow-left" @click="changeDateForMonth('pre')" style="margin-left: 10px"></i>
      </div>
      <div class="calendar-header-btn">
        <span>{{ currentDate.currentYear }}年{{ currentDate.currentMonth }}月</span>
      </div>

      <div class="calendar-header-btn ">
        <i class="el-icon-arrow-right" @click="changeDateForMonth('next')" style="margin-right: 10px"></i>
        <i class="el-icon-d-arrow-right" @click="changeDateForYear('next')"></i>
      </div>

    </div>
    <!-- 分割 -->
    <el-divider></el-divider>
    <!-- 日历表 -->
    <div class="calendar-body">
      <!-- 星期列 -->
      <div class="calendar-body-week">
        <div
          :class="item.value === currentDate.currentWeek ? 'calendar-day-box-selected calendar-day-box': 'calendar-day-box'"
          v-for="(item,index) in weeArray" :key="item.value">
          <div style="border-radius: 50%;">
            <span>{{ item.cn_label }}</span>
          </div>
        </div>
      </div>
      <!-- 日期表 -->
      <div class="calendar-body-date">
        <div class="calendar-day-box"
             :class="item.isNow ? 'calendar-day-box-selected calendar-day-box': 'calendar-day-box'"
             v-for="(item,index) in calendarList" :key="index">
          <span :class="item.isNonCurrentMonth ? 'non-current-month':'' ">{{ item.currentDay }}</span>
        </div>
      </div>
    </div>
    <el-divider></el-divider>
    <div class="task-box">
      <div class="task-box-tag">
        <el-tabs :stretch="true" v-model="activeName" @tab-click="changeTaskType">
          <el-tab-pane name="SystemTask">
            <span slot="label">
             系统任务({{ taskList.systemTask.nonCompletedSum }})
            </span>
          </el-tab-pane>
          <el-tab-pane name="CustomTask">
            <span slot="label">
             自定义任务({{ taskList.customTask.nonCompletedSum }})
            </span>
          </el-tab-pane>
        </el-tabs>
      </div>
      <div>
        <el-button type="primary" v-if="activeName === 'CustomTask'" size="mini">新建</el-button>
        <el-button size="mini">查看全部</el-button>
      </div>
    </div>
    <div class="task-list" v-if=" currentTaskList && currentTaskList.length > 0">
      <div v-for="(item, index) in currentTaskList" :key="index" class="task-list-item">
        <div class="task-list-item-box">
          <div>
            <svg-icon :icon-class="item.taskDegreeLevelType || 'general'"></svg-icon>
          </div>
          <div class="task-list-item-view">
            <div class="task-list-item-title">
              <span>{{ item.taskName }}</span>
            </div>
            <div class="task-list-item-info">
              <span>来自:{{ item.from }} | {{ item.pushDate }}</span>
            </div>
          </div>
        </div>
        <div>
          <tag-view :tag-id="item.taskStatus"
                    :tags="staticOptions['TaskStatus']">
          </tag-view>
        </div>
        <div>
          <el-button type="text">查看详情</el-button>
        </div>
      </div>
    </div>
    <div class="task-list" v-else>
      <el-empty description="暂无任务数据"></el-empty>
    </div>
  </div>
</template>

<script>
import {weekDisplayList} from '@/utils/constant'
import {getDashboardTaskPanel} from "@/api/task";
import {getStaticOptions} from "@/api/resources";
import TagView from "@/components/TagView";

export default {
  name: "Calendar",
  components: {TagView},
  data() {
    return {
      staticOptionsScopes: 'TaskType,TaskStatus',
      staticOptions: {},

      weeArray: weekDisplayList,
      currentDate: {
        currentYear: 1900,
        currentMonth: 1,
        currentDay: 1,
        currentWeek: 0,
      },
      calendarList: [],

      activeName: 'SystemTask',
      taskList: {
        systemTask: {
          nonCompletedSum: 0,
          taskList: []
        },
        customTask: {
          nonCompletedSum: 0,
          taskList: []
        }
      },
      currentTaskList: []


    }
  },
  created() {

  },
  mounted() {
    this.$nextTick(function () {
      this.init()
    })
  },
  methods: {
    async init() {
      await this.initOptions()
      await this.initCalendar()
      await this.initTaskList()
    },
    initCalendar() {
      console.log("initCalendar")
      const date = new Date()
      this.currentDate.currentYear = date.getFullYear() + ''
      this.currentDate.currentMonth = date.getMonth() + 1
      // 月份是从0开始的(0-11)
      this.currentDate.currentDay = date.getDate()
      this.currentDate.currentWeek = date.getDay()
      console.log('initCalendar', this.currentDate)
      //
      this.getCalendarBox(this.currentDate)
    },
    initOptions() {
      console.log("initOptions")
      getStaticOptions(this.staticOptionsScopes).then(res => {
        this.staticOptions = res.data
      })
    },
    initTaskList() {
      console.log("initTaskList")
      let startTime = new Date(this.currentDate.currentYear + '-' + this.currentDate.currentMonth + '-' + this.currentDate.currentDay + ' 00:00:00').getTime()
      let endTime = new Date(this.currentDate.currentYear + '-' + this.currentDate.currentMonth + '-' + this.currentDate.currentDay + ' 23:59:59').getTime()
      getDashboardTaskPanel(startTime, endTime).then(res => {
        this.taskList = res.data
        this.changeTaskList()
      })
    },
    getCalendarBox(currentDate) {
      this.calendarList = []
      // 唯一知道的只有这个封装的时间类
      // 获取当前月的第一天的date和最后一天的date
      let startDateStr = currentDate.currentYear + '-' + currentDate.currentMonth + '-' + '1'
      let endDateStr = currentDate.currentYear + '-' + currentDate.currentMonth + '-' + this.getMonthDays(currentDate.currentYear, currentDate.currentMonth, currentDate.currentDay, 0)

      let startDate = new Date(startDateStr)
      let endDate = new Date(endDateStr)

      // 判断第一天是否是周日 不是周日向前推到周日
      // 周日是 0
      if (startDate.getDay() !== 0) {
        let preYear = currentDate.currentYear
        let preMonth = currentDate.currentMonth
        if (currentDate.currentMonth === 1) {
          preMonth = 12
          preYear = preYear - 1
        } else {
          preMonth = preMonth - 1
        }
        // 获取上个月的最后一天
        let preLastDay = this.getMonthDays(preYear, preMonth, 1, 0);
        for (let i = startDate.getDay(); i > 0; i--) {
          let preDay = preLastDay - i
          let preDate = new Date(preYear + '-' + preMonth + '-' + preDay)
          let dateObj = {
            currentYear: preYear,
            currentMonth: preMonth,
            currentDay: preDate.getDate(),
            currentWeek: preDate.getDay(),
            isNow: false,
            isNonCurrentMonth: true,
            inlineWeek: false
          }
          this.calendarList.push(dateObj)
        }
      }
      // 补齐中间数据 也就是当前月
      let nowYear = new Date().getFullYear() + ''
      let nowMonth = new Date().getMonth() + 1
      let nowDay = new Date().getDate()
      let nowWeek = new Date().getDay()

      for (let i = 1; i <= endDate.getDate(); i++) {
        let _currentDate = new Date(currentDate.currentYear + '-' + currentDate.currentMonth + '-' + i)
        let dateObj = {
          currentYear: _currentDate.getFullYear(),
          currentMonth: _currentDate.getMonth() + 1,
          currentDay: _currentDate.getDate(),
          currentWeek: _currentDate.getDay(),
          isNow: false,
          isNonCurrentMonth: false,
          inlineWeek: false
        }

        // 判断当前日期节点
        if (parseInt(nowYear) === parseInt(dateObj.currentYear)
          && parseInt(nowMonth) === parseInt(dateObj.currentMonth)
          && parseInt(nowDay) === parseInt(dateObj.currentDay)) {
          dateObj.isNow = true
        }
        this.calendarList.push(dateObj)
      }
      // 补齐尾部数据

      if (endDate.getDay() !== 6) {
        let nextYear = currentDate.currentYear
        let nextMonth = currentDate.currentMonth
        if (currentDate.currentMonth === 12) {
          nextMonth = 1
          nextYear = nextYear + 1
        } else {
          nextMonth = nextMonth + 1
        }
        // 获取下个月个月的最后一天
        let len = 6 - endDate.getDay()
        for (let i = 1; i <= len; i++) {
          let nextMonthDay = new Date(nextYear + '-' + nextMonth + '-' + i)
          let dateObj = {
            currentYear: nextMonthDay.getFullYear(),
            currentMonth: nextMonthDay.getMonth() + 1,
            currentDay: nextMonthDay.getDate(),
            currentWeek: nextMonthDay.getDay(),
            isNow: false,
            isNonCurrentMonth: true,
            inlineWeek: false
          }
          this.calendarList.push(dateObj)
        }
      }
      console.log('getCalendarBox', this.calendarList)
    },
    getMonthDays(year, month, day, val) {
      let date = new Date(year + '-' + month + '-' + day)
      // 获取当前页面的天数
      date.setMonth(date.getMonth() + 1); // 先设置为下个月
      date.setDate(val); // 再置0,变成当前月最后一天
      return date.getDate();
    },
    changeDateForMonth(type) {
      // 最小粒度是从月份开始的
      if (type === 'pre') {
        // 推前
        if (this.currentDate.currentMonth === 1) {
          this.currentDate.currentYear = this.currentDate.currentYear - 1
          this.currentDate.currentMonth = 12
        } else {
          this.currentDate.currentMonth = this.currentDate.currentMonth - 1
        }
      } else {
        // 推后一个月
        if (this.currentDate.currentMonth === 12) {
          this.currentDate.currentYear = this.currentDate.currentYear + 1
          this.currentDate.currentMonth = 1
        } else {
          this.currentDate.currentMonth = this.currentDate.currentMonth + 1
        }
      }
      // 2月份比较特殊 要判断最后一天
      let lastDay = this.getMonthDays(this.currentDate.currentYear, this.currentDate.currentMonth, 1, 0);
      console.log('lastDay', lastDay)
      //
      if (this.currentDate.currentDay > lastDay) {
        this.currentDate.currentDay = lastDay
      }
      console.log('changeDate', this.currentDate)
      this.getCalendarBox(this.currentDate)
    },
    changeDateForYear(type) {
      // 最小粒度是从月份开始的
      if (type === 'pre') {
        // 推前
        this.currentDate.currentYear = this.currentDate.currentYear - 1
      } else {
        // 推后一个月
        this.currentDate.currentYear = this.currentDate.currentYear + 1
      }
      let lastDay = this.getMonthDays(this.currentDate.currentYear, this.currentDate.currentMonth, 1, 0);
      console.log('lastDay', lastDay)
      //
      if (this.currentDate.currentDay > lastDay) {
        this.currentDate.currentDay = lastDay
      }
      console.log('changeDate', this.currentDate)
      this.getCalendarBox(this.currentDate)
    },
    changeTaskType(tab, event) {
      console.log('changeTaskType', tab, event, this.activeName)
      this.changeTaskList()
    },
    changeTaskList() {
      this.currentTaskList = []
      if (this.activeName === 'SystemTask') {
        console.log("initTaskList", this.taskList.systemTask.tasksList)
        this.currentTaskList = this.taskList.systemTask.tasksList
      } else {
        this.currentTaskList = this.taskList.customTask.tasksList
      }
    }
  }
}
</script>

<style scoped lang="scss">
.el-divider {
  margin: 10px 0;
}

.calendar-footer {
  cursor: pointer;
  text-align: center;
  margin: 0 auto;
  width: 68px;
  height: 34px;
  border-radius: 10px 10px 0 0;
  box-shadow: 0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .04);
}

.calendar-header {
  display: flex;
  flex-direction: row;
  flex-wrap: nowrap;
  justify-content: space-between;
  align-items: center;
  font-weight: 600;

  .calendar-header-btn {
    cursor: pointer;
    width: 100px;
    text-align: center;
  }

  .left {
    display: flex;
    flex-direction: row;
  }

  .right {
    display: flex;
    flex-direction: row-reverse
  }
}

.calendar-day-box {
  width: 88px;
  height: 44px;
  display: flex;
  justify-content: center;
  align-items: center;
  border-radius: 5px
}

.calendar-body {
  text-align: center;
  min-height: 308px;

  .calendar-body-week {
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: space-around;
  }

  .calendar-body-date {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-around;

  }
}

.task-box {
  display: flex;
  flex-direction: row;
  flex-wrap: nowrap;
  justify-content: space-between;
  align-items: center;

  .task-box-tag {
    width: 250px;
  }
}

.task-list {
  height: 308px;
  overflow: auto;

  .task-list-item {
    display: flex;
    flex-direction: row;
    flex-wrap: nowrap;
    justify-content: space-between;
    align-items: center;
    margin: 20px 0;

    .task-list-item-box {
      display: flex;

      .task-list-item-view {
        margin: 0 35px;

        .task-list-item-title {
          font-weight: 900;
          margin-bottom: 10px;
        }

        .task-list-item-info {
          font-size: 15px;
        }
      }
    }


  }
}
</style>

方法的数据结构可以自己定义

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
Vue Element 日程日历即使用 Vue.jsElement UI 组件库进行开发的日程管理和日历展示组件。该组件可以方便地添加、删除和编辑日程,并且可以按照日期进行展示和筛选。 在 Vue Element 日程日历中,可以通过使用 Element UI 中的表单和弹出框组件轻松地创建新的日程。用户可以选择日期和时间,设置标题和描述等信息,并且可以给每个日程添加自定义的样式。同时,也可以通过编辑功能来对已有的日程进行修改。 日历视图是 Vue Element 日程日历的核心功能之一。它可以以日、周、月等不同的视图来展示日程,并且支持点击日期或时间的功能。在日历视图中,用户可以看到自己已创建的日程,可以通过拖拽和调整大小的方式来改变日程的时间和持续时间。此外,日历视图还可以根据不同的筛选条件来展示特定的日程,帮助用户更好地管理和查看自己的安排。 Vue Element 日程日历还提供了日期选择器和快速导航功能,让用户可以方便地切换日期和浏览不同的时间段。用户可以通过点击日期选择器中的日期来切换到特定的日期,也可以通过快速导航按钮来切换到今天、明天、上一周或下一周等时间段。 总之,Vue Element 日程日历是一个功能强大且易于使用的日程管理和日历展示组件。它可以帮助用户方便地创建、编辑和查看日程,并且可以根据不同的视图和筛选条件展示特定的日程。无论是个人用户还是企业用户,都可以通过使用 Vue Element 日程日历来更好地计划和安排自己的时间。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我的钱包空指针了

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值