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

日历组件模板

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

<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
      )
    }
  }
}

进阶功能实现

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

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

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

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

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

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

vue实现每日签到日历

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

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

相关文章

vue实现分屏

vue实现分屏

Vue 实现分屏的方法 分屏功能通常用于展示多个独立内容区域,以下是几种常见的实现方式: 使用 CSS Grid 布局 通过 CSS Grid 可以轻松创建分屏布局,在 Vue 组件中直接应用样式:…

vue实现tag

vue实现tag

Vue 实现标签(Tag)功能 在 Vue 中实现标签(Tag)功能可以通过多种方式完成,以下是一些常见的方法和实现步骤: 使用动态组件和 v-for 通过 v-for 指令动态渲染标签列表,结合样…

vue实现长按

vue实现长按

Vue 实现长按功能的方法 在 Vue 中实现长按功能可以通过原生事件监听或自定义指令完成。以下是几种常见实现方式: 使用原生事件监听 通过 @mousedown 和 @mouseup 或 @tou…

vue实现webapp

vue实现webapp

Vue 实现 WebApp 的基本步骤 环境准备 确保已安装 Node.js 和 npm/yarn。通过 Vue CLI 或 Vite 创建项目: npm install -g @vue/cli v…

vue底层实现

vue底层实现

Vue.js 的底层实现原理 Vue.js 是一个渐进式 JavaScript 框架,其核心实现主要包括响应式系统、虚拟 DOM、模板编译和组件化机制。以下是其关键实现细节: 响应式系统 Vue 2…

vue拼图实现

vue拼图实现

实现 Vue 拼图游戏的方法 使用 Vue 组件和动态数据绑定 创建一个 Vue 组件来管理拼图的状态和逻辑。通过 v-for 动态渲染拼图块,利用 v-bind 绑定样式和位置。拼图块的数据可以存储…