当前位置:首页 > 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 实现文件树的方法 使用递归组件 递归组件是处理嵌套数据结构的理想方式。文件树通常包含文件夹和文件的嵌套结构,适合用递归组件实现。 <template> <ul>…

vue状态管理怎么实现

vue状态管理怎么实现

Vue 状态管理实现方法 使用 Vuex(官方推荐) Vuex 是 Vue 的官方状态管理库,适合中大型应用。 安装 Vuex: npm install vuex --save 创建 Store…

vue实现上移下移插件

vue实现上移下移插件

实现上移下移功能的 Vue 插件 在 Vue 中实现列表项的上移和下移功能,可以通过自定义指令或组件封装的方式完成。以下是两种常见实现方式: 基于数组操作的通用方法 通过操作数组索引实现元素位置交…

vue实现密码框的包

vue实现密码框的包

Vue 密码框实现方案 在 Vue 中实现密码框功能,可以通过原生 HTML 结合 Vue 指令或使用第三方组件库完成。以下是几种常见方案: 原生 HTML + Vue 双向绑定 <temp…

vue实现右下角弹框

vue实现右下角弹框

实现右下角弹框的基本思路 在Vue中实现右下角弹框,通常需要结合CSS定位和Vue的组件化特性。弹框可以通过绝对定位固定在右下角,并通过Vue控制其显示与隐藏。 创建弹框组件 新建一个Vue组件(如…

用vue实现滑动输入条

用vue实现滑动输入条

使用 Vue 实现滑动输入条 使用原生 HTML5 input range 实现 在 Vue 模板中直接使用 <input type="range">,通过 v-model 绑定数据:…