首先需要引入animate动画组件下载css样式
animate动画库下载提取码: k9qz
html
<template>
<div class="sign">
<!-- 遮罩层 -->
<div class="shade" v-bind:style="show">
<div class="shadearray animated bounceInDown">
<div>
<img
src="signimg/backgroundcard.png"
style="max-width: 324px"
alt=""
/>
</div>
<div>
<img
src="signimg/close.png"
style="max-width: 29px"
alt=""
@click="close"
/>
</div>
</div>
</div>
<img class="banner-img" src="signimg/signbanner.png" alt="" />
<div class="header-title">
<div>
<img style="width: 8px; height: 15px" src="signimg/upicon.png" alt="" />
</div>
<div>每日签到</div>
</div>
<div class="header-array">
<div>
<div class="header-card">
<div>已坚持</div>
<div class="header-cardicon">
<div>
<img
style="width: 45px; height: 62px"
src="signimg/cardicon.png"
alt=""
/>
<div class="header-num">{{ a }}</div>
</div>
<div>
<img
style="width: 45px; height: 62px"
src="signimg/cardicon.png"
alt=""
/>
<div class="header-num">{{ b }}</div>
</div>
<div>
<img
style="width: 45px; height: 62px"
src="signimg/cardicon.png"
alt=""
/>
<div class="header-num">{{ c }}</div>
</div>
</div>
<div>天签到</div>
</div>
<div class="header-text">连续签到有礼相伴~</div>
</div>
</div>
<div style="width: 100%; padding: 0px 15px 0px 15px; magrin-bottom: ">
<div class="signcard-header">
<div>
<div>已连续签到</div>
<div style="font-size: 20px; color: #ff4e00">{{ signdata.days }}</div>
<div>天</div>
</div>
<div class="signdatemonth">
<div class="signdatemonth-padding">
<div @click="pickPre(currentYear, currentMonth)">
<img
style="width: 8px; height: 15px"
src="signimg/lasticon.png"
alt=""
/>
</div>
<div style="font-size: 16px">
{{ currentYear }}年{{ currentMonth }}月
</div>
<div @click="pickNext(currentYear, currentMonth)">
<img
style="width: 8px; height: 15px"
src="signimg/nexticon.png"
alt=""
/>
</div>
</div>
</div>
<div class="signcard-section">
<div class="signcard-title">
<div>周日</div>
<div>周一</div>
<div>周二</div>
<div>周三</div>
<div>周四</div>
<div>周五</div>
<div>周六</div>
</div>
</div>
<div class="signcard-footer">
<div class="signcard-list">
<div v-for="day in days" :key="day.item">
<!-- 这里是已签到的 -->
<div
class="signagree"
v-if="day.isSign && day.day.getMonth() + 1 === currentMonth"
>
<img
style="max-width: 27px"
src="signimg/agreeicon.png"
alt=""
/>
<div style="color: rgb(85, 195, 109)">
{{ currentMonth }}.{{ day.day.getDate() }}
</div>
</div>
<!-- 这里是未签到的 -->
<div
class="signagree"
v-if="!day.isSign && day.day.getMonth() + 1 === currentMonth"
>
<img
style="max-width: 27px"
src="signimg/agreegrayicon.png"
alt=""
/>
<div>{{ currentMonth }}.{{ day.day.getDate() }}</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div v-if="datestatus == 0" class="card-buttonfrom animated rotateIn">
<div @click="Sign">马上签到</div>
</div>
<div v-else-if="datestatus == 1" class="card-buttonfromgrey animated swing">
<div>签到成功</div>
</div>
</div>
</template>
css
//这里引入animate动画库
@import "../../animate/animate.min.css";
*{
margin: 0;
padding: 0;
}
.shade{
width: 100%;
height: 100vh;
background-color: rgba(0,0,0,0.5);
position: fixed;
align-items: center;
flex-wrap: wrap;
z-index: 2;
padding-top: 60px;
}
.shadearray>div{
width: 100%;
display: flex;
justify-content: center;
}
body{
background-color: rgb(245, 245, 245);
}
.sign{
display: flex;
justify-content: center;
flex-wrap: wrap;
}
.banner-img{
width: 100%;
height: 234px;
position: absolute;
top: 0px;
z-index: -1;
}
.header-title{
display: flex;
justify-content: center;
align-items: flex-end;
position: relative;
}
.header-title{
width: 100%;
height: 67px;
color: white;
font-size: 17px;
img{
position: absolute;
left: 20px;
bottom: 2px;
}
}
.header-array{
width: 100%;
margin-top: 33px;
margin-bottom: 17px;
height: 88px;
padding: 0px 54px 0px 54px;
}
.header-array>:first-child{
height: 88px;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
flex-wrap: wrap;
}
.header-card{
width: 100%;
display: flex;
justify-content: center;
align-items: center;
color: white;
font-size: 18px;
}
.header-card>div:nth-child(1){
margin-right: 5px;
}
.header-card>div:nth-child(3){
margin-left: 5px;
}
.header-text{
width: 100%;
line-height: 28px;
color: white;
text-align: center;
font-size: 13px;
}
.header-cardicon{
position: relative;
div{
margin: 0px 2px 0px 2px;
display: flex;
justify-content: center;
align-items: center;
}
display: flex;
justify-content: center;
align-items: center;
.header-num{
position: absolute;
font-size: 40px;
color: #ff8400;
}
}
.signcard-header{
width: 100%;
background-color: white;
border-radius: 10px;
padding-top: 5px;
padding-bottom: 20px;
overflow: hidden;
letter-spacing:1px
}
.signcard-header>div:first-child{
padding-left: 20px;
font-size: 12px;
display: flex;
justify-content: start;
align-items: center;
color: rgb(139, 139, 139);
}
.signdatemonth{
width: 100%;
}
.signdatemonth-padding{
padding: 5px 20px 5px 20px;
display: flex;
justify-content: space-between;
font-size: 16px;
align-items: center;
}
.signcard-section{
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 5px;
margin-bottom: 5px;
}
.signcard-title{
width: 100%;
display: flex;
justify-content: space-between;
padding-left: 20px;
padding-right: 20px;
font-size: 12px;
}
.signcard-title>div{
width:14.2%;
display: flex;
justify-content: center;
align-items: center;
}
.signcard-footer{
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
}
.signcard-list{
width: 100%;
display: flex;
justify-content: start;
padding-left: 20px;
padding-right: 20px;
font-size: 12px;
flex-wrap: wrap;
}
.signcard-list>div{
width:14.2%;
margin-top: 5px;
margin-bottom: 5px;
display: flex;
justify-content: center;
align-items: center;
flex-wrap: wrap;
position: relative;
}
.signagree{
display: flex;
justify-content: center;
align-items: center;
flex-wrap: wrap;
}
.signcard-list>div>img{
z-index: 1;
}
.signdate{
width: 100%;
display: flex;
justify-content: center;
}
.signsolid{
width: 100%;
height: 2px;
background-color: #efefef;
z-index: 0;
position: absolute;
top: 13px;
}
.card-buttonfrom{
margin-top: 26px;
display: flex;
justify-content: center;
align-items: center;
padding: 15px 80px 15px 80px;
color: white;
border-radius: 50px;
font-size: 18px;
background: linear-gradient(rgb(255,118,45), rgb(255,79,1));
}
.card-buttonfromgrey{
margin-top: 26px;
display: flex;
justify-content: center;
align-items: center;
background: #b5b5b5;
padding: 15px 80px 15px 80px;
color: white;
border-radius: 50px;
font-size: 18px;
letter-spacing:2px
}
js
<script src="http://cdn.bootcss.com/Mock.js/1.0.0/mock-min.js"></script>
<script>
import "./sign.scss";
// import Axios from 'axios'
import { sign, signclick } from "@/modules/sign.modules.js";
export default {
data() {
return {
signdata: "",
message: [],
cardshow: "",
currentDay: "", // 当前天
currentMonth: "", // 当前月
currentYear: "",
currentWeek: 1, // 一号所在的星期
days: [], // 当月所有天数
content: {},
arrDate: [], // 当月签到日期
num: 0,
day: 4,
show: {
display: "none",
},
datestatus: 1,
a: "",
b: "",
c: "",
num:''
};
},
created() {
this.initData();
},
mounted() {
this.getSingRecord(this.currentYear,this.currentMonth);
},
methods: {
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)
);
date = new Date(this.formatDate(d.getFullYear(), d.getMonth() + 1, 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; // 初始化日期
for (var i = this.currentWeek; i > 0; i--) {
const d = new Date(str);
d.setDate(d.getDate() - i);
var dayobject = {};
dayobject.day = d;
this.days.push(dayobject);
}
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);
}
},
// 判断日期是否有签到
isVerDate(v) {
// console.log(v,'判断是否有签到')
return this.arrDate.includes(v);
},
// 点击上个月进行的操作
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));
this.getSingRecord(this.currentYear,this.currentMonth);
},
// 点击下个月进行的操作
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));
this.getSingRecord(this.currentYear,this.currentMonth);
},
// 返回 类似 2020-01-01 格式的字符串
formatDate(year, month, day) {
month < 10 && (month = "0" + month);
day < 10 && (day = "0" + day);
const data = year + "-" + month + "-" + day;
return data;
},
Sign() {
(this.datetrue = false),
(this.datefalse = true),
(this.show = { display: "block" });
console.log(this.arrDate);
signclick({ id: "1" }).then((res) => {
if (res.code == 200) {
console.log("成功");
} else if (res.code == 0) {
console.log("失败");
}
});
},
close() {
this.buttontext = "签到完成";
this.cardshow = 2;
this.show = { display: "none" };
this.getSingRecord(this.currentYear,this.currentMonth);
},
getSingRecord(year,month) {
// 这里是接口
sign({
id: 1,
year: year,
month: month,
}).then((res) => {
this.signdata=res
this.datestatus=res.status
var day=String(res.day)
// 这里是签到的天数
this.a=day.charAt(0);
this.b=day.charAt(1);
this.c=day.charAt(2);
var cd=[...this.days]
this.days.forEach(val => {
try{
for(let i=0;i<res.signlist.length;i++){
if(val.day.getDate() == res.signlist[i].day){
val.isSign = true;
}
}
}catch{
console.log('失败.')
}
})
});
},
},
};
</script>
接口模板
{code: 200, msg: null, status: 1, day: 155, days: 162, signlist: [{day: 6}, {day: 7}]}
code: 200
day: 155
days: 162
msg: null
signlist: [{day: 6}, {day: 7}]
status: 1