倒计时组件的封装
Posted robot666
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了倒计时组件的封装相关的知识,希望对你有一定的参考价值。
uni-ui中也是有类似的插件(电商h5页面经常会用到的),可以根据自身的需求去做相应的改变
https://ext.dcloud.net.cn/search?q=%E5%80%92%E8%AE%A1%E6%97%B6
<template>
<view class="uni-countdown" :class="{miaosha:miaosha}">
<text v-if="showDay" :style="{ borderColor: borderColor, color: color, backgroundColor: backgroundColor }" class="uni-countdown__number">{{ d }}</text>
<text v-if="showDay" :style="{ color: splitorColor }" class="uni-countdown__splitor">天</text>
<text :style="{ borderColor: borderColor, color: color, backgroundColor: backgroundColor }" class="uni-countdown__number">{{ h }}</text>
<text :style="{ color: splitorColor }" class="uni-countdown__splitor">{{ showColon ? ‘:‘ : ‘时‘ }}</text>
<text :style="{ borderColor: borderColor, color: color, backgroundColor: backgroundColor }" class="uni-countdown__number">{{ i }}</text>
<text :style="{ color: splitorColor }" class="uni-countdown__splitor">{{ showColon ? ‘:‘ : ‘分‘ }}</text>
<text :style="{ borderColor: borderColor, color: color, backgroundColor: backgroundColor }" class="uni-countdown__number">{{ s }}</text>
<text v-if="!showColon" :style="{ color: splitorColor }" class="uni-countdown__splitor">秒</text>
</view>
</template>
<script>
export default {
name: ‘UniCountdown‘,
props: {
miaosha: {
type: Boolean,
default: false
},
showDay: {
type: Boolean,
default: true
},
showColon: {
type: Boolean,
default: true
},
backgroundColor: {
type: String,
default: ‘#FFFFFF‘
},
borderColor: {
type: String,
default: ‘#000000‘
},
color: {
type: String,
default: ‘#000000‘
},
splitorColor: {
type: String,
default: ‘#000000‘
},
day: {
type: Number,
default: 0
},
hour: {
type: Number,
default: 0
},
minute: {
type: Number,
default: 0
},
second: {
type: Number,
default: 0
}
},
data() {
return {
timer: null,
syncFlag: false,
d: ‘00‘,
h: ‘00‘,
i: ‘00‘,
s: ‘00‘,
leftTime: 0,
seconds: 0
}
},
watch: {
day(val) {
this.changeFlag()
},
hour(val) {
this.changeFlag()
},
minute(val) {
this.changeFlag()
},
second(val) {
this.changeFlag()
}
},
created: function(e) {
this.startData();
},
beforeDestroy() {
clearInterval(this.timer)
},
methods: {
toSeconds(day, hours, minutes, seconds) {
return day * 60 * 60 * 24 + hours * 60 * 60 + minutes * 60 + seconds
},
timeUp() {
clearInterval(this.timer)
this.$emit(‘timeup‘)
},
countDown() {
let seconds = this.seconds
let [day, hour, minute, second] = [0, 0, 0, 0]
if (seconds > 0) {
day = Math.floor(seconds / (60 * 60 * 24))
hour = Math.floor(seconds / (60 * 60)) - (day * 24)
minute = Math.floor(seconds / 60) - (day * 24 * 60) - (hour * 60)
second = Math.floor(seconds) - (day * 24 * 60 * 60) - (hour * 60 * 60) - (minute * 60)
} else {
this.timeUp()
}
if (day < 10) {
day = ‘0‘ + day
}
if (hour < 10) {
hour = ‘0‘ + hour
}
if (minute < 10) {
minute = ‘0‘ + minute
}
if (second < 10) {
second = ‘0‘ + second
}
this.d = day
this.h = hour
this.i = minute
this.s = second
},
startData() {
this.seconds = this.toSeconds(this.day, this.hour, this.minute, this.second)
if (this.seconds <= 0) {
return
}
this.countDown()
this.timer = setInterval(() => {
this.seconds--
if (this.seconds < 0) {
this.timeUp()
return
}
this.countDown()
}, 1000)
},
changeFlag() {
if (!this.syncFlag) {
this.seconds = this.toSeconds(this.day, this.hour, this.minute, this.second)
this.startData();
this.syncFlag = true;
}
}
}
}
</script>
<style lang="scss" scoped>
@import ‘~@/uni.scss‘;
$countdown-height: 48rpx;
$countdown-width: 52rpx;
.uni-countdown {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
justify-content: flex-start;
padding: 2rpx 0;
}
.uni-countdown__splitor {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
justify-content: center;
line-height: $countdown-height;
padding: 5rpx;
font-size: $uni-font-size-sm;
}
.uni-countdown__number {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
justify-content: center;
align-items: center;
width: $countdown-width;
height: $countdown-height;
line-height: $countdown-height;
margin: 5rpx;
text-align: center;
font-size: $uni-font-size-sm;
}
.miaosha{
height: 165rpx;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 50rpx;
.uni-countdown__number{
border-radius:50%;
line-height: 100rpx;
height:100rpx;
width: 100rpx;
box-sizing: border-box;
border: 10rpx solid #8BC7E8 !important;
color: #8BC7E8 !important;
}
.uni-countdown__splitor{
line-height: 100rpx;
height: 100rpx;
color: #8BC7E8 !important;
font-size: 30rpx;
font-weight: bold;
}
}
</style>
在父组件中的引用,做到如下:
<uniCountDown @timeup="timeup" color="#FFFFFF" :show-day="false" background-color="#FC4444" splitor-color="#FC4444" border-color="#FC4444" :hour="hours" :minute="minutes" :second="seconds"/>
timeup传入事件如下:
timeup(){
var nowDate = new Date()
var tomorrow = new Date(new Date(new Date().toLocaleDateString()).getTime() +24 * 60 * 60 * 1000)
var timestamp = tomorrow.getTime() - nowDate.getTime(); //时间差的毫秒数
//计算出相差天数
var days = Math.floor(timestamp / (24 * 3600 * 1000))
//计算出小时数
var leave1 = timestamp % (24 * 3600 * 1000) //计算天数后剩余的毫秒数
var hours = Math.floor(leave1 / (3600 * 1000))
//计算相差分钟数
var leave2 = leave1 % (3600 * 1000) //计算小时数后剩余的毫秒数
var minutes = Math.floor(leave2 / (60 * 1000))
//计算相差秒数
var leave3 = leave2 % (60 * 1000) //计算分钟数后剩余的毫秒数
var seconds = Math.round(leave3 / 1000)
this.hours = hours
this.minutes = minutes
this.seconds = seconds
console.log(hours, minutes, seconds)
},
后面记得在mouted生命周期调用!
以上是关于倒计时组件的封装的主要内容,如果未能解决你的问题,请参考以下文章
Vue.js 自定义组件封装实录——基于现有控件的二次封装(以计时器为例)