本文实例为大家分享了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; ? ? } ? } }
签到效果:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
声明:本文来自网络,不代表【好得很程序员自学网】立场,转载请注明出处:http://haodehen.cn/did121411