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

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

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

vue实现每日签到日历

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

相关文章

vue实现好友列表

vue实现好友列表

实现好友列表的Vue组件 数据准备 在Vue组件的data中定义好友列表数据,通常是一个数组对象,每个对象包含好友的基本信息如ID、头像、昵称等。 data() { return {…

vue弹幕实现不重叠

vue弹幕实现不重叠

实现 Vue 弹幕不重叠的方法 CSS 定位与动画控制 通过绝对定位和动态计算弹幕轨道高度,确保弹幕在不同轨道上运行。每条弹幕占据固定高度的轨道,避免重叠。 // 弹幕轨道高度计算 const t…

vue实现本地数据存储

vue实现本地数据存储

使用 localStorage 或 sessionStorage Vue 中可以直接调用浏览器提供的 localStorage 或 sessionStorage API 进行数据存储。localSto…

vue实现收起展开面板

vue实现收起展开面板

实现收起展开面板的方法 在Vue中实现收起展开面板功能可以通过多种方式完成,以下是几种常见的实现方法: 使用v-show或v-if控制显示隐藏 利用Vue的指令可以轻松实现面板的展开和收起:…

vue实现文章锚点定位

vue实现文章锚点定位

实现文章锚点定位的方法 在Vue中实现文章锚点定位可以通过多种方式完成,以下是几种常见的方法: 使用原生HTML锚点 通过HTML的id属性和<a>标签的href属性实现锚点跳转。在Vu…

vue 方法实现

vue 方法实现

在 Vue 中,方法的实现通常通过 methods 选项完成。以下是 Vue 方法实现的核心要点和示例: 基本方法定义 在 Vue 组件中定义方法时,需将函数声明放在 methods 对象内。这些…