vue倒計時無縫迴圈上下切換(1秒切換一次帶動畫)
阿新 • • 發佈:2021-03-21
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>