当前位置:首页 > VUE

vue实现每日签到日历

2026-02-20 19:17:15VUE

实现思路

使用Vue实现每日签到日历需要结合日期处理、状态管理和UI渲染。核心逻辑包括生成当月日历数据、标记签到状态、处理签到交互。

日历数据生成

创建计算属性生成当月日历数组,包含上月残留天数、当月天数及下月补充天数:

computed: {
  calendarDays() {
    const year = this.currentDate.getFullYear();
    const month = this.currentDate.getMonth();

    // 当月第一天星期几(0-6)
    const firstDay = new Date(year, month, 1).getDay();
    // 当月总天数
    const totalDays = new Date(year, month + 1, 0).getDate();

    const days = [];

    // 上月残留天数
    const prevMonthDays = new Date(year, month, 0).getDate();
    for (let i = firstDay - 1; i >= 0; i--) {
      days.push({
        date: prevMonthDays - i,
        currentMonth: false,
        signed: false
      });
    }

    // 当月天数
    for (let i = 1; i <= totalDays; i++) {
      days.push({
        date: i,
        currentMonth: true,
        signed: this.signedDates.includes(`${year}-${month + 1}-${i}`)
      });
    }

    // 补充下月天数
    const remaining = 42 - days.length;
    for (let i = 1; i <= remaining; i++) {
      days.push({
        date: i,
        currentMonth: false,
        signed: false
      });
    }

    return days;
  }
}

签到状态管理

使用数组存储已签到日期,格式化为YYYY-M-D字符串:

data() {
  return {
    signedDates: [],
    currentDate: new Date()
  }
},
methods: {
  signIn() {
    const today = new Date();
    const dateStr = `${today.getFullYear()}-${today.getMonth() + 1}-${today.getDate()}`;

    if (!this.signedDates.includes(dateStr)) {
      this.signedDates.push(dateStr);
    }
  }
}

日历UI渲染

使用CSS Grid布局7x6的日历表格:

<template>
  <div class="calendar">
    <div class="header">
      <button @click="prevMonth">上一月</button>
      <h3>{{ monthTitle }}</h3>
      <button @click="nextMonth">下一月</button>
    </div>

    <div class="weekdays">
      <div v-for="day in ['日','一','二','三','四','五','六']" :key="day">{{ day }}</div>
    </div>

    <div class="days">
      <div 
        v-for="(day, index) in calendarDays" 
        :key="index"
        :class="{
          'other-month': !day.currentMonth,
          'signed': day.signed,
          'today': isToday(day)
        }"
        @click="handleDayClick(day)"
      >
        {{ day.date }}
        <span v-if="day.signed" class="sign-mark">✓</span>
      </div>
    </div>
  </div>
</template>

样式设计

基础日历样式示例:

.calendar {
  width: 350px;
  font-family: Arial;
}

.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 10px;
}

.weekdays, .days {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
}

.weekdays div {
  padding: 10px;
  text-align: center;
  font-weight: bold;
}

.days div {
  padding: 10px;
  height: 40px;
  display: flex;
  justify-content: center;
  align-items: center;
  position: relative;
  cursor: pointer;
}

.days div.other-month {
  color: #ccc;
}

.days div.signed {
  background-color: #e8f5e9;
}

.days div.today {
  border: 1px solid #2196F3;
}

.sign-mark {
  position: absolute;
  bottom: 2px;
  right: 2px;
  color: #4CAF50;
  font-size: 12px;
}

完整功能扩展

  1. 连续签到统计:增加计算属性统计连续签到天数
  2. 签到奖励:根据连续签到天数显示不同奖励
  3. 数据持久化:使用localStorage存储签到记录
  4. 动画效果:签到时添加CSS动画增强交互体验
// 连续签到计算示例
computed: {
  consecutiveDays() {
    // 实现连续签到逻辑
    let count = 0;
    const today = new Date();

    for (let i = 0; i <= 6; i++) {
      const date = new Date(today);
      date.setDate(date.getDate() - i);
      const dateStr = `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`;

      if (this.signedDates.includes(dateStr)) {
        count++;
      } else {
        break;
      }
    }

    return count;
  }
}

vue实现每日签到日历

标签: 日历vue
分享给朋友:

相关文章

vue实现按钮刷新

vue实现按钮刷新

Vue 实现按钮刷新功能 在 Vue 中实现按钮刷新功能可以通过多种方式实现,具体取决于刷新需求是局部刷新还是全局刷新。以下是几种常见的方法: 使用 window.location.reload()…

vue实现边框

vue实现边框

Vue 实现边框的方法 在 Vue 中实现边框效果可以通过多种方式完成,包括内联样式、CSS 类绑定、动态样式以及使用第三方 UI 库。以下是几种常见的实现方法。 内联样式绑定 使用 Vue 的 :…

vue实现iframe

vue实现iframe

Vue 中实现 iframe 的方法 在 Vue 项目中,可以通过多种方式实现 iframe 的嵌入。以下是几种常见的方法: 使用原生 HTML iframe 标签 直接在 Vue 组件的模板中使用…

vue实现suspense

vue实现suspense

Vue 3 中实现 Suspense Suspense 是 Vue 3 引入的一个内置组件,用于处理异步依赖的加载状态。它允许在等待异步组件或异步数据加载时显示一个后备内容(fallback),直到异…

vue tab实现

vue tab实现

Vue Tab 实现方法 使用动态组件实现 Tab 在 Vue 中可以通过动态组件 <component :is="currentTab"> 结合 v-for 和 v-bind 实现 Ta…

vue登录实现

vue登录实现

Vue 登录实现 实现登录功能通常需要前端与后端配合,Vue 作为前端框架,主要负责表单处理、请求发送和状态管理。以下是常见的实现方式: 表单设计与数据绑定 使用 Vue 的 v-model 实现…