vue倒计时无缝循环上下切换(1秒切换一次带动画)
之前也在网上找了倒计时切换的不少文章,大同小异,干脆还是自己写得了。
1.代码比较简单,也不多做介绍了,直接新建一个组件,将代码拉进去就行。
2. 给组件传一个参数:rangeTime=86600,作为剩余时间,单位:秒。
<template>
<div class="item-time-box">
<div class="time-cell">
<div class="time-cell-box">
<div class="time-list" :style="{top:getScrollTop.day+'px'}">
<div>30</div>
<div v-for="(item,index) of 31" :key="index">
{{index>=10?index:'0'+index}}
</div>
</div>
</div>
<span>日</span>
</div>
<div class="time-cell">
<div class="time-cell-box">
<div class="time-list" :class="{'clear-transtion':downReset.hour}" :style="{top:getScrollTop.hour+'px'}">
<div>23</div>
<div v-for="(item,index) of 24" :key="index">
{{index>=10?index:'0'+index}}
</div>
</div>
</div>
<span>时</span>
</div>
<div class="time-cell">
<div class="time-cell-box">
<div class="time-list" :class="{'clear-transtion':downReset.minute}" :style="{top:getScrollTop.minute+'px'}">
<div>59</div>
<div v-for="(item,index) of 60" :key="index">
{{index>=10?index:'0'+index}}
</div>
</div>
</div>
<span>分</span>
</div>
</div>
</template>
<script>
export default {
props:{
rangeTime:{ // 剩余时间,单位秒
type:Number,
default:0
}
},
computed:{
getScrollTop(){
// -36: 因为给0上面加了最后一个数,用于无缝滚动
let day = this.timeData.day*-36-36;
// 如果是23时,并且没有执行重回,就滚动到第一个(第一个就是复制的最后一个)
let hour = (this.timeData.hour==23 && !this.downReset.hour)?0:this.timeData.hour*-36-36;
// 如果是59分,并且没有执行重回,就滚动到第一个(第一个就是复制的最后一个)
let minute = (this.timeData.minute==59 && !this.downReset.minute)?0:this.timeData.minute*-36-36;
return {day,hour,minute}
},
},
data(){
return {
timeData:{ // 面板上显示的时间 (天时分)
day:0,
hour:0,
minute:0,
},
downReset:{ // (时分)是否重回到最后一个
hour:false,
minute:false,
}
}
},
mounted(){
if(this.rangeTime>0){
// 显示初始化时间
this.getSurplusTime(this.rangeTime);
// 进入倒计时
this.downTime();
}
},
methods:{
downTime(){ // 倒计时
let second = this.rangeTime;
let times = setInterval(()=>{
if(second<=0){
clearInterval(times);
times=null;
setTimeout(()=>{
// this.$message.success('奖金通知已发送');
this.$emit('runTimer'); // 倒计时结束,触发方法
},500)
return false;
}
second-=60; // 我是以分为单位,为了更好的看效果,每秒定时器 - 1分钟
this.getSurplusTime(second);
},1000)
},
getSurplusTime(second){ // 获取剩余时间
let minute=0;
let hour=0;
let day=0;
minute = parseInt(second/60);
if(minute>=60) {
hour = parseInt(minute/60);
minute%=60;
}
if(hour>=24){
day = parseInt(hour/24);
hour%=24;
}
this.timeData={day,hour,minute};
if((hour==23 && !this.downReset.hour) || (minute==59 && !this.downReset.minute)){
// 先将位置移到第一个
this.downReset={
hour:false,
minute:false
}
// 如果有时/分,到了最大值,320毫秒后,定位到最后一个
// 为什么要定位:如果没有重定位,最大值显示的位置是复制的第一个的位置。需要定时器取消动画,定位到最后,实现无缝环形效果
setTimeout(()=>{
this.downReset={
hour:hour==23,
minute:minute==59
}
},320)
}else{
this.downReset={
hour:hour==23,
minute:minute==59
}
}
}
}
}
</script>
<style lang="scss" scoped>
.item-time-box{
height: 90px;
border-radius: 4px;
background: #F1F1F1;
box-shadow: 0 0 5px 0 #ccc inset;
margin-bottom: 5px;
padding: 10px 20px;
display: flex;
justify-content: space-between;
align-items: center;
.time-cell{
text-align: center;
.time-cell-box{
position: relative;
overflow: hidden;
width: 36px;
height: 36px;
line-height: 36px;
border-radius: 3px;
background: #0089D1;
box-shadow: 0 0 10px 0 rgb(20, 20, 20,0.2) inset;
color:#fff;
font-size: 20px;
margin-bottom: 5px;
.time-list{
position: absolute;
transition:all 0.3s;
top: 0;
left: 0;
width: 100%;
&.clear-transtion{
transition:none;
}
}
}
}
}
</style>