当前位置:首页 > 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>

样式设计

基础日历样式示例:

vue实现每日签到日历

.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实现xss

vue实现xss

XSS 攻击简介 XSS(跨站脚本攻击)是一种常见的安全漏洞,攻击者通过注入恶意脚本到网页中,当其他用户访问该页面时,脚本会在其浏览器中执行,可能导致数据泄露或会话劫持。 Vue 中的 XSS…

vue实现滑块

vue实现滑块

Vue 实现滑块组件的方法 使用原生 HTML 和 Vue 指令 通过 Vue 的 v-model 和事件监听实现基础滑块功能。创建一个包含 input 元素的组件,类型设置为 range,并绑定到…

vue实现ssr

vue实现ssr

Vue 实现 SSR(服务端渲染) Vue 的服务端渲染(SSR)允许在服务器端生成完整的 HTML 内容,再发送到客户端,提升首屏加载速度和 SEO 友好性。以下是实现 Vue SSR 的关键步骤和…

vue实现通讯

vue实现通讯

Vue 组件通讯方法 父子组件通讯 父组件向子组件传递数据通过 props,子组件向父组件传递数据通过 $emit 事件。 父组件模板: <child-component :message=…

vue 实现折叠

vue 实现折叠

Vue 实现折叠功能的方法 在 Vue 中实现折叠功能可以通过多种方式完成,以下是几种常见的实现方法: 使用 v-if 或 v-show 控制显示隐藏 通过绑定一个布尔值变量,结合 v-if 或 v…

vue实现模糊

vue实现模糊

Vue实现模糊搜索的方法 在Vue中实现模糊搜索功能通常需要结合输入框和列表渲染,通过监听输入内容动态过滤数据。以下是几种常见实现方式: 使用计算属性实现 计算属性适合处理需要响应式更新的搜索逻辑:…