手写一个日历,记录签到-vue3

<template>
  <div class="calendar">
    <div class="header">
      <div class="header_left">
        <div class="totals">195</div>
        <div class="names">累计学习天数</div>
      </div>
      <div class="header_right">
        <div class="arrows" @click="prevMonth"><img src="../../../assets/Layout/home/icon_arrowleft.png" alt="" class="arrow_image"></div>
        <span class="same_month">{{ currentYear }}.{{ (currentMonth + 1).toString().padStart(2, '0') }}</span>
        <div class="arrows" @click="nextMonth"><img src="../../../assets/Layout/home/icon_arrowright.png" alt="" class="arrow_image"></div>
      </div>
    </div>
    <div class="weekdays">
      <div v-for="(day, index) in weekdays" :key="index" class="weekday">{{ day }}</div>
    </div>
    <div class="days">
      <div  v-for="(day, index) in days"  :key="index"  class="day"  :class="{ selected: isSelected(day) }"  @click="day && toggleDateSelection(day)">
        {{ day ? day.getDate() : '' }}
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed } from 'vue';

    const currentDate = ref(new Date());
    const selectedDates = ref(new Set());
    const weekdays = ['一', '二', '三', '四', '五', '六', '日'];
    const currentYear = computed(() => currentDate.value.getFullYear());
    const currentMonth = computed(() => currentDate.value.getMonth());

    const days = computed(() => {
      const firstDayOfMonth = new Date(currentYear.value, currentMonth.value, 1);
      const lastDayOfMonth = new Date(currentYear.value, currentMonth.value + 1, 0);
      const firstDayOfWeek = firstDayOfMonth.getDay();
      const daysInMonth = lastDayOfMonth.getDate();

      const calendarDays = [];
      for (let i = 0; i < firstDayOfWeek; i++) {
        calendarDays.push(null); // empty cells for previous month days
      }
      for (let day = 1; day <= daysInMonth; day++) {
        calendarDays.push(new Date(currentYear.value, currentMonth.value, day));
      }
      return calendarDays;
    });

    const toggleDateSelection = (day) => {
      if (!day) return;
      const dateString = day.toISOString().split('T')[0];
      if (selectedDates.value.has(dateString)) {
        selectedDates.value.delete(dateString);
      } else {
        selectedDates.value.add(dateString);
      }
    };

    const isSelected = (day) => {
      if (!day) return false;
      const dateString = day.toISOString().split('T')[0];
      return selectedDates.value.has(dateString);
    };

    const prevMonth = () => {
      currentDate.value = new Date(currentYear.value, currentMonth.value - 1, 1);
    };

    const nextMonth = () => {
      currentDate.value = new Date(currentYear.value, currentMonth.value + 1, 1);
    };

</script>

<style lang="scss" scoped>
.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 30px;
  .header_left{
    .totals{
    font-family: Oswald;
    font-weight: 700;
    font-size: 40px;
    background: linear-gradient(to bottom, #E87421 , #FBCE89 );
    background-clip: text;
    -webkit-background-clip: text;
    color: transparent;
    }
    .names{
      font-weight: 400;
      font-size: 14px;
      color: rgb(0, 0, 0,.7);
    }
  }
  .header_right{
    display: flex;
    align-items: center;
    .arrow_image{
      width: 17px;
      height: 12px;
    }
    .same_month{
      margin: 0 15px;
      font-family: Oswald;
      font-weight: 700;
      font-size: 16px;
      color: rgb(0, 0, 0,.7);
    }
    .arrows{
      cursor: pointer;
    }
  }
}
.weekdays {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 5px;
  font-weight: bold;
  text-align: center;
  margin-bottom: 10px;
  font-size: 12px;
}
.days {
  display: grid;
  grid-template-columns: repeat(7, 1fr);

}

.day {
  padding:10px;
  box-sizing: border-box;
  text-align: center;
  cursor: pointer;
  font-weight: bold;
  font-size: 12px;
  margin: 8px;
}

.day.selected {
  background: linear-gradient(-90deg, #27C5D4, #69EAF6);
  box-shadow: 0px 0px 8px 0px rgba(36,196,211,0.35);
  border-radius: 22px;
  color: #fff;
}
</style>

Spring Boot是一个开源的Java框架,用于快速构建基于Java的企业级应用程序。Vue一个开源的JavaScript框架,用于构建用户界面。 在你提到的日历签到系统中,可以使用Spring Boot作为后端框架,提供API接口和数据处理功能。Vue可以作为前端框架,用于构建用户界面,与后端进行数据交互和展示。 首先,你可以使用Spring Boot创建一个基本的Java项目。在项目中,你可以定义用户类、签到记录类等实体类,用于存储用户和签到信息。 接下来,你可以使用Spring Boot的数据库操作技术,如JPA或MyBatis,创建数据库表和关联关系。你可以创建用户表和签到记录表,将用户和签到信息存储在数据库中。 然后,你可以使用Spring Boot编写API接口,用于处理用户的注册、登录、签到等功能。通过定义控制器类和相应的方法,你可以实现用户的注册、登录和签到逻辑。 在前端方面,你可以使用Vue创建一个单页应用程序。你可以使用Vue的组件化思想,将用户界面分解为多个可重用的组件。你可以创建日历组件、签到记录组件等,然后将它们组合在一起。 通过Vue的路由功能,你可以定义不同页面之间的跳转和关系。例如,你可以创建一个注册页面、登录页面和签到页面,并通过路由进行相应的跳转。 最后,你可以使用Vue的异步请求功能,通过API接口与后端进行数据交互。你可以发送请求,获取用户和签到信息,并在前端展示出来。 总的来说,通过使用Spring Boot构建后端API接口,Vue构建前端用户界面,你可以实现一个基于Spring Boot和Vue日历签到系统。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值