vue实现签到日历效果

本文实例为大家分享了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;
    }
  }
}

签到效果:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • mpvue实现小程序签到金币掉落动画(api实现)

    这里使用小程序自带的api来实现,用小程序来写动画的恶心点在于,没有帧,只能用setimeout 来作为帧来使用, 下面是实现代码, 下面是简单用div代替了图片,需要什么图片,可以自行替换相应的div即可 需要变成原生小程序,则需要修改一下代码的写法 效果图: 创建金币动画组件 clockAnimation.vue <template> <div class="container" v-if='isShow'> <!-- 创建金币对象 --> &l

  • 基于element日历组件实现签卡记录

    本文实例为大家分享了基于element日历组件实现签卡记录的具体代码,供大家参考,具体内容如下 使用element日历组件为基础,实现可以查看每天签卡记录 <template>   <div class="n-container">     <div style="padding: 40px">       <el-col :span="24">         <div class=&quo

  • vue实现签到日历效果

    本文实例为大家分享了vue实现签到日历效果的具体代码,供大家参考,具体内容如下 先看看我们的效果图: 一.页面部分: <template>   <div class="test-page">     <div class="top">       <div class="button" v-if="!sign" @click="Sign">         &

  • vue实现价格日历效果

    本文实例为大家分享了vue实现价格日历效果的具体代码,供大家参考,具体内容如下 1.效果图 2.下载全局安装:npm install ele-calendar 3.在components下新建文件calendar.vue,内容: <template> <div style="width:600px"> <ele-calendar :render-content="renderContent" :data="datedef&qu

  • 使用Vue实现简单日历效果

    使用Vue实现简单的日历,供大家参考,具体内容如下 原理分析: 1.获取当前时间2.显示当前时间3.点击增加和减少月份4.大月和小月的天数 效果演示 初始样式(显示现在的日期时间) 增加一个月 在程序开始之前一定注意: 引入Vue.js架包 代码演示 Body内容 <script type="text/x-template" id="calendar">    <!-- 年份-->        <div id="year&q

  • Vue.js创建Calendar日历效果

    使用 Vue.js 进行数据与视图的绑定,数据更新会让视图自动进行更新,类似 Android 里面的 DataBinding. 实现一个HTML的日历效果. html 部分 <div id="calendar"> <!-- 年份 月份 --> <div class="month"> <ul> <li class="arrow" @click="pickPre(currentYear,

  • vue实现周日历切换效果

    本文实例为大家分享了vue实现周日历切换效果的具体代码,供大家参考,具体内容如下 废话不多说,直接上干货,需要的朋友自取 代码: <!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8">     <meta http-equiv="X-UA-Compatible" content="IE=edge"

  • jQuery实现日历效果

    本文实例为大家分享了jQuery实现日历效果的具体代码,供大家参考,具体内容如下 jquery是用的是2.0版本. 1.html代码 <!DOCTYPE html> <!--基于W3C标准 不用做任何修改--> <html> <!--起始标准--> <head> <!--设置初始化文档信息和文档管理标注--> <meta http-equiv="Content-Type" content="text

  • 用vue写一个日历

    之前在上家公司做过一个公司人员考勤的东西,里面需要用到日历,当时自己用vue随便写了一个,比较简单,删掉了其他功能的代码,只留下日历,直接看代码 <template> <div class="lookForMonth_wrapper"> <div class="lookForMonth_top"> <div class="selectDate"> <div>{{year}} 年 {{mo

  • Vue.js实现拖放效果的实例

    页面效果如下所示: 代码请看这里,当当当当: html: <template> <div class='drag-content'> <div class='project-content'> <div class='select-item' draggable='true' @dragstart='drag($event)' v-for='pjdt in projectdatas'>{{pjdt.name}}</div> </div>

  • bootstrap vue.js实现tab效果

    本文实例为大家分享了bootstrap vue.js实现tab效果的具体代码,供大家参考,具体内容如下 项目目录结构 Student.js代码 function Student(){ this.baseInfo = { tabStatus : true , name : '张三', sex : 'male' } , this.parentsInfo = { tabStatus : false, fatherName : '张全蛋', motherName : '李铁柱' } , this.stu

  • js实现会跳动的日历效果(完整实例)

    一.简介 编写一个会动的日历,日历上面有年月日,周几,时分秒,效果如下: 年月日,周几,时分秒都会随着系统时间的走动而改变 二.代码 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scal

随机推荐