vue + 签到日历

先看看我们的效果图:
在这里插入图片描述
一、页面部分:

<template>
  <div class="test-page">
    <div class="top">
      <div class="button" v-if="!sign" @click="Sign">
        <i class="calendar-icon"></i>
        <div>去签到</div>
      </div>
      <div class="button" v-if="sign">
        <i class="calendar-icon"></i>
        <div>已签到</div>
      </div>
      <div>已连续签到{{day}}天,继续加油!</div>
    </div>

    <div class="content">
      <!-- 年份 月份 -->
      <ul class="month bottom-line">
        <!--点击会触发pickpre函数,重新刷新当前日期 -->
        <li class="arrow" @click="pickPre(currentYear,currentMonth)"><van-icon name="arrow-left"/> 上个月</li>
        <li class="year-month">
          <span>{{ currentYear }}-{{ currentMonth }}</span>
        </li>
        <li class="arrow" @click="pickNext(currentYear,currentMonth)">下个月 <van-icon name="arrow"/></li>
      </ul>

      <!-- 星期 -->
      <ul class="weekdays">
        <li>日</li>
        <li>一</li>
        <li>二</li>
        <li>三</li>
        <li>四</li>
        <li>五</li>
        <li>六</li>
      </ul>

      <!-- 日期 -->
      <ul class="days bottom-line">
        <li  v-for="day in days">
          <!--本月已签到日期-->
          <span v-if="day.isSign && day.day.getMonth()+1 === currentMonth" class="cli">
            <img src="/static/images/calendar-sign-icon.png">
            {{ day.day.getDate() }}
          </span>
          <!--本月未签到日期-->
          <span v-if="!day.isSign && day.day.getMonth()+1 === currentMonth" class="cli">{{ day.day.getDate() }}</span>
        </li>
      </ul>
    </div>

    <div class="role">
      <div class="role-title">签到规则</div>
      <div class="role-content" v-html="role ? role : '暂无内容'"></div>
    </div>
  </div>
</template>

<script>
import index from './index';
export default index;
</script>

<style lang="less" scoped>
@import './index';
</style>

二:js部分:

import { Cell, CellGroup, Field, Popup, Button, Icon } from 'vant';

export default {
  components: {
    [Cell.name]: Cell,
    [CellGroup.name]: CellGroup,
    [Field.name]: Field,
    [Popup.name]: Popup,
    [Button.name]: Button,
    [Icon.name]: Icon
  },
  data() {
    return {
      currentDay: 1, // 当前天
      currentMonth: 1, // 当前月
      currentYear: 1970,
      currentWeek: 1, // 一号所在的星期
      days: [], // 当月所有天数
      content: {},
      arrDate: [], // 当月签到日期
      num: 0,
      day: 10,
      sign: false,
      role: '<p>每天签到可获得5个能量</p>'
    };
  },
  created() {
    this.getSign();
  },
  methods: {
    /**
     * 获取签到日期
     */
    getSign() {
      // 接口未完成,模拟数据
      const sign_days = [
        { day: 5 }, { day: 1 }, { day: 2 }, { day: 3 }, { day: 4 }, { day: 6 }, { day: 7 }, { day: 8 }, { day: 9 }, { day: 10 }
      ];
      for (const i in sign_days) {
        this.arrDate.push(sign_days[i].day);
      }
      this.initData(null);
    },
    initData(cur) {
      let date;
      if (cur) { // 切换日期
        date = new Date(cur);
      } else {
        var now = new Date();
        var d = new Date(this.formatDate(now.getFullYear(), now.getMonth() + 1, 1));
        d.setDate(35);// 设置天数为35天
        date = new Date(this.formatDate(d.getFullYear(), d.getMonth(), 1));
      }
      this.currentDay = date.getDate(); // 今日日期 几号
      this.currentYear = date.getFullYear(); // 当前年份
      this.currentMonth = date.getMonth() + 1; // 当前月份

      this.currentWeek = date.getDay(); // 0,1...6 星期
      const str = this.formatDate(this.currentYear, this.currentMonth, this.currentDay); // 2020-01-01
      this.days.length = 0; // 初始化日期
      // 如果今天是周日,放在第一行第7个位置,前面6个 这里默认显示一周,如果需要显示一个月,则第二个循环为 i<= 35- this.currentWeek
      for (var i = this.currentWeek; i > 0; i--) {
        const d = new Date(str);
        d.setDate(d.getDate() - i);
        var dayobject = {}; // 用一个对象包装Date对象  以便为以后预定功能添加属性
        dayobject.day = d;
        this.days.push(dayobject); // 将日期放入data 中的days数组 供页面渲染使用
      }
      // 其他周 // 设置天数为35天,周日设置在第一位,循环从36开始
      this.num = 0;
      for (var j = 0; j <= 36 - this.currentWeek; j++) {
        const d = new Date(str);
        d.setDate(d.getDate() + j);
        const dddd = d.getDate();
        if (dddd === 1) {
          this.num++;
        }
        if (this.num === 2) {
          return;
        }
        const dayobject = { day: d, isSign: this.isVerDate(dddd) };
        this.days.push(dayobject);
      }
    },
    /**
     * 判断该日期是否有签到
     * @param v
     * @returns {boolean}
     */
    isVerDate(v) {
      return this.arrDate.includes(v);
    },
    /**
     * 上一月
     * @param year
     * @param month
     */
    pickPre(year, month) {
      const d = new Date(this.formatDate(year, month, 1));
      d.setDate(0);
      this.initData(this.formatDate(d.getFullYear(), d.getMonth() + 1, 1));
    },
    /**
     * 下一月
     * @param year
     * @param month
     */
    pickNext(year, month) {
      const d = new Date(this.formatDate(year, month, 1));
      d.setDate(35);
      this.initData(this.formatDate(d.getFullYear(), d.getMonth() + 1, 1));
    },
    // 返回 类似 2020-01-01 格式的字符串
    formatDate(year, month, day) {
      month < 10 && (month = '0' + month);
      day < 10 && (day = '0' + day);
      const data = year + '-' + month + '-' + day;
      return data;
    },
    /**
     * 点击签到
     * @param index
     */
    Sign() {
      const now = new Date();
      this.arrDate.push(now.getDate());
      this.initData();
      this.sign = true;
      // 接口待完成,虚拟提示
      this.$fn.success('签到成功');
    }
  }
};

三、CSS部分:

.test-page {
  .top {
    background: url('/static/images/user-bg-img.jpg') no-repeat 0 0;
    background-size: 100% 100%;
    overflow: hidden;
    color: #ffffff;
    padding: 15px;
    height: 120px;
    text-align: center;
    .button {
      display: flex;
      justify-content: center;
      border: 1px solid #ffffff;
      border-radius: 20px;
      color: #ffffff;
      font-size: 18px;
      width: 120px;
      margin: 0 auto 10px;
      height: 40px;
      line-height: 40px;
      .calendar-icon {
        display: block;
        width: 40px;
        height: 40px;
        background: url(/static/images/calendar-icon.png) no-repeat -6px -4px;
        background-size: 114px 45px;
      }
    }
    .button:active {
      background-color: #5283c4;
      opacity: 0.8;
    }
  }

  .content {
    margin: 0 15px;
    border-radius: 8px;
    overflow: hidden;
    margin-top: -40px;
    box-shadow: rgba(225,225,225,0.7) 0  10px 20px 0;
  }
  .month {
    background: #ffffff;
    margin: 0;
    padding: 10px 15px;
    display: flex;
    justify-content: space-between;
    li {
      text-transform: uppercase;
      letter-spacing: 0;
    }
    .arrow {
      color: #5283c4;
      font-size: 12px;
      i {
        font-size: 13px;
        top: 2px;
      }
    }
    .year-month { font-size: 17px; }
  }

  .weekdays { /*头部星期*/
    margin: 0;
    padding: 10px 0;
    background-color: #ffffff;
    display: flex;
    flex-wrap: wrap;
    justify-content: space-around;
    li {
      display: inline-block;
      text-align: center;
    }
  }

  .days { /*日期*/
    padding: 0 0 10px;
    background: #FFFFFF;
    margin: 0;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-start;

    li {
      list-style-type: none;
      width: 14.2%;
      padding: 1%;
      box-sizing: border-box;
      height: 40px;
      margin-bottom: 4px;
      text-align: center;
      color: #000;
      .cli {
        position: relative;
        width: 100%;
        height: 40px;
        display: flex;
        align-items: center;
        justify-content: center;
        img {/*签到的日期*/
          height: 40px;
          position: absolute;
        }
      }
    }
  }

  .role {
    padding: 20px 15px;
    .role-title {
      margin-bottom: 5px;
      font-weight: bold;
    }
    .role-content {
      font-size: 13px;
      color: #333333;
    }
  }
}

签到效果:
在这里插入图片描述
在这里插入图片描述

注:前端小白,主要是怕自己忘记,方便日后使用,哈哈

  • 18
    点赞
  • 69
    收藏
    觉得还不错? 一键收藏
  • 30
    评论
Vue Element 日程日历即使用 Vue.js 和 Element UI 组件库进行开发的日程管理和日历展示组件。该组件可以方便地添加、删除和编辑日程,并且可以按照日期进行展示和筛选。 在 Vue Element 日程日历中,可以通过使用 Element UI 中的表单和弹出框组件轻松地创建新的日程。用户可以选择日期和时间,设置标题和描述等信息,并且可以给每个日程添加自定义的样式。同时,也可以通过编辑功能来对已有的日程进行修改。 日历视图是 Vue Element 日程日历的核心功能之一。它可以以日、周、月等不同的视图来展示日程,并且支持点击日期或时间的功能。在日历视图中,用户可以看到自己已创建的日程,可以通过拖拽和调整大小的方式来改变日程的时间和持续时间。此外,日历视图还可以根据不同的筛选条件来展示特定的日程,帮助用户更好地管理和查看自己的安排。 Vue Element 日程日历还提供了日期选择器和快速导航功能,让用户可以方便地切换日期和浏览不同的时间段。用户可以通过点击日期选择器中的日期来切换到特定的日期,也可以通过快速导航按钮来切换到今天、明天、上一周或下一周等时间段。 总之,Vue Element 日程日历是一个功能强大且易于使用的日程管理和日历展示组件。它可以帮助用户方便地创建、编辑和查看日程,并且可以根据不同的视图和筛选条件展示特定的日程。无论是个人用户还是企业用户,都可以通过使用 Vue Element 日程日历来更好地计划和安排自己的时间。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 30
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值