uniapp 之 签到日历组件📅

1,831 阅读2分钟

效果图

image.png

要周五了,简简单单给大家表演一个吧,祝各位周末愉快👀


页面结构

image.png

这里需要分成3个部分来写

image.png

日期部分,这里用到 grid 布局。

.calendar-grid {
  display: grid;
  grid-template-columns: repeat(7, 14.28%);
  .calendar-grid-item {
    //....
  }
}

不熟的小伙伴,可以看一下阮一峰老师的文章:ruanyifeng.com/blog/2019/0…

数据结构

type data {
  year: number,
  month: number,
  day: number,
  prevMonth?: boolean,
  nextMonth?: boolean,
  today: boolean,
  check: boolean,
  value: number
}

初始化日期天数 initCalendar()

nowYear: new Date().getFullYear(),
nowMonth: new Date().getMonth() + 1,
maxDayList: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
initCalendar() {
  const maxDayList = [...this.maxDayList];
  const year = this.nowYear;
  const month = this.nowMonth;
}

计算当前年是不是闰年,规则:能被4整除且不被100整除,或者能被400整除的年份

maxDayList[1] = (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0 ? 29 : 28;

this.maxDayList = maxDayList;

累计当天天数

let days = [];
for (let index = 1; index <= maxDayList[month - 1]; index++) {
  days.push({
    year,
    month,
    day: index,
    today: false,
    check: false,
    value: 0,
  });
}

image.png

需要补的前置天数,需要处理是否是本年的月份

let beforeDays = [];

当前月的1号是星期几,0是星期天

let firstDayWeek = new Date(year + "/" + month + "/1").getDay();
let nowYear = this.nowYear;
let previousMonth = month - 1;
let previousMonthIndex = month - 2;
if (previousMonthIndex < 0) {
  previousMonthIndex = 11;
  nowYear = nowYear - 1;
  previousMonth = 12;
}
for (let index = 0; index < firstDayWeek; index++) {
  let day = maxDayList[previousMonthIndex] - index;
  beforeDays.push({
    year,
    month: previousMonth,
    day,
    prevMonth: true,
    check: false,
    value: 0,
  });
}

需要补的后置天数

let afterDays = [];

当前月最后一天是星期几

let endDayWeek = new Date(year + "/" + month + "/" + maxDayList[month - 1]).getDay();
let afterDays = [];
for (let index = 1; index < 7 - endDayWeek; index++) {
  afterDays.push({
    year,
    month: newxMonth,
    day: index,
    nextMonth: true,
    check: false,
    value: 0,
  });
}

image.png

判断日期是否是今天 isToDay()

let currentYear = new Date().getFullYear();
let currentMonth = new Date().getMonth() + 1;
let currentDay = new Date().getDate();

if (
  currentDay === day &&
  this.nowYear === currentYear &&
  this.nowMonth === currentMonth
)
  return true;
return false;

修改累计天数代码

for (let index = 1; index <= maxDayList[month - 1]; index++) {
  days.push({
    year,
    month,
    day: index,
    //-----
    today: this.isToDay(index),
    //----
    check: false,
    value: 0,
  });
}

image.png

判断用户是否已签到 getCheckState()

组件接收一个对象数组

[
  { date: "20230928", signInFlag: true, xbCount: 7 },
  { date: "20230927", signInFlag: true, xbCount: 6 },
  { date: "20230926", signInFlag: true, xbCount: 5 },
]
let currentMonth = month > 9 ? month : "0" + month;
let currentDay = day > 9 ? day : "0" + day;
let curentDate = `${year}${currentMonth}${currentDay}`;
let item = this.values?.find((item) => item.date === curentDate);
if (item) return { check: true, value: item.xbCount };
return {};

在三个 for 循环中,对 push 的数据进行修改。

for (let index = 1; index <= maxDayList[month - 1]; index++) {
  let { check, value } = this.getCheckState(year, month, index);
  days.push({
    year,
    month,
    day: index,
    today: this.isToDay(index),
    check,
    value,
  });
}
for (let index = 0; index < firstDayWeek; index++) {
  let day = maxDayList[previousMonthIndex] - index;
  let { check, value } = this.getCheckState(
    nowYear,
    previousMonthIndex + 1,
    day
  );
  beforeDays.push({
    year,
    month: previousMonth,
    day,
    prevMonth: true,
    check,
    value,
  });
}
for (let index = 1; index < 7 - endDayWeek; index++) {
  let { check, value } = this.getCheckState(nowYear, newxMonth, index);
  afterDays.push({
    year,
    month: newxMonth,
    day: index,
    nextMonth: true,
    check,
    value,
  });
}

image.png

完整代码:gitee.com/suiboyu/eve…

麻烦各位给个 star