当前位置:首页 > VUE

vue实现每日签到日历

2026-01-20 03:15:20VUE

实现每日签到日历的基本思路

使用Vue实现每日签到日历需要结合日期处理和组件化设计。核心功能包括生成当月日历数据、标记签到状态以及交互逻辑。

日历数据生成

通过JavaScript的Date对象处理日期,生成当月所有天数数组,并标记是否为当前月份:

methods: {
  generateCalendar() {
    const date = new Date()
    const year = date.getFullYear()
    const month = date.getMonth()

    const firstDay = new Date(year, month, 1)
    const lastDay = new Date(year, month + 1, 0)

    const days = []
    // 上个月末尾几天
    for (let i = 0; i < firstDay.getDay(); i++) {
      days.push({ day: null, currentMonth: false })
    }
    // 当月所有天数
    for (let i = 1; i <= lastDay.getDate(); i++) {
      days.push({ 
        day: i, 
        currentMonth: true,
        signed: this.isSigned(year, month, i)
      })
    }
    return days
  }
}

签到状态管理

使用Vuex或组件状态管理签到数据,通常需要与后端API交互:

methods: {
  async handleSign(day) {
    if (this.isSigned(day)) return

    try {
      await api.signIn() // 调用签到API
      this.$set(day, 'signed', true)
    } catch (error) {
      console.error('签到失败', error)
    }
  },
  isSigned(year, month, day) {
    // 检查本地存储或状态中是否已签到
    return this.signedDates.includes(`${year}-${month+1}-${day}`)
  }
}

日历组件模板

使用网格布局展示日历,包含星期标题和日期单元格:

vue实现每日签到日历

<template>
  <div class="calendar">
    <div class="weekdays">
      <div v-for="day in ['日','一','二','三','四','五','六']" :key="day">
        {{ day }}
      </div>
    </div>
    <div class="days">
      <div 
        v-for="(day, index) in days" 
        :key="index"
        :class="{ 
          'current-month': day.currentMonth,
          'signed': day.signed,
          'today': isToday(day)
        }"
        @click="handleSign(day)"
      >
        {{ day.day }}
        <span v-if="day.signed" class="sign-mark">✓</span>
      </div>
    </div>
  </div>
</template>

样式设计

基础日历样式确保布局整齐,突出显示可交互元素:

.calendar {
  width: 100%;
  max-width: 400px;
  margin: 0 auto;
}

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

.days div {
  height: 40px;
  line-height: 40px;
  border: 1px solid #eee;
  cursor: pointer;
}

.current-month {
  background: white;
}

.signed {
  background-color: #e8f5e9;
  color: #2e7d32;
}

.today {
  border: 2px solid #2196f3 !important;
}

.sign-mark {
  color: #4caf50;
  font-weight: bold;
}

完整组件示例

将上述代码整合为可复用的Vue组件:

export default {
  data() {
    return {
      days: [],
      signedDates: [] // 应从后端获取或本地存储加载
    }
  },
  created() {
    this.days = this.generateCalendar()
  },
  methods: {
    // 包含前面提到的所有方法
    isToday(day) {
      if (!day.currentMonth) return false
      const today = new Date()
      return (
        today.getDate() === day.day && 
        today.getMonth() === this.currentMonth
      )
    }
  }
}

进阶功能实现

对于更复杂的需求,可以考虑以下扩展:

vue实现每日签到日历

连续签到计数功能需要后端支持记录连续签到天数,前端展示进度:

computed: {
  continuousDays() {
    // 计算连续签到天数逻辑
    return this.signedDates.filter(/* 连续条件 */).length
  }
}

签到奖励系统可在连续签到特定天数时触发:

watch: {
  continuousDays(newVal) {
    if (newVal === 3) this.showReward(1)
    if (newVal === 7) this.showReward(2)
  }
}

响应式设计确保在不同设备上正常显示:

@media (max-width: 600px) {
  .days div {
    height: 30px;
    line-height: 30px;
    font-size: 12px;
  }
}

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

相关文章

vue实现字母添加排序

vue实现字母添加排序

实现字母添加排序的方法 在Vue中实现字母添加排序功能,可以通过以下步骤完成: 创建Vue实例并定义数据 new Vue({ el: '#app', data: { letters…

vue实现模块

vue实现模块

Vue 实现模块化的方法 Vue 支持多种模块化开发方式,可以根据项目需求选择适合的方案。 使用单文件组件(SFC) 单文件组件是 Vue 最常用的模块化方式,将模板、脚本和样式封装在一个 .vue…

vue实现active

vue实现active

Vue 实现 active 状态的方法 在 Vue 中实现 active 状态可以通过以下几种方式实现,具体取决于使用场景和需求。 使用 v-bind:class 动态绑定类名 通过 v-bind:…

vue  实现tab

vue 实现tab

实现 Tab 切换功能 在 Vue 中实现 Tab 切换功能可以通过动态组件或条件渲染完成。以下是两种常见方法: 使用 v-if 或 v-show 实现条件渲染 通过绑定 currentTab 变量…

vue实现slidetoggle

vue实现slidetoggle

Vue 实现 SlideToggle 效果 SlideToggle 是一种常见的交互效果,元素以滑动方式展开或收起。以下是几种实现方法: 使用 CSS Transition 和 v-show 通过…

vue实现ppt

vue实现ppt

Vue 实现 PPT 的功能 Vue 可以结合第三方库或自定义组件实现类似 PPT 的演示效果。以下是几种常见的方法: 使用第三方库 reveal.js reveal.js 是一个流行的演示框架,支…