Skip to content

Commit

Permalink
feat: 新增倒计时组件
Browse files Browse the repository at this point in the history
  • Loading branch information
zhangzhenfei committed Sep 28, 2020
1 parent 6a140a5 commit 9540b6b
Show file tree
Hide file tree
Showing 4 changed files with 183 additions and 12 deletions.
159 changes: 149 additions & 10 deletions components/pi-count-down/index.vue
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
<template>
<view
class="pi-width-100P"
:style="[customStyle, { height: `${statusBarHeight}px`, background: background }]"
:class="[customClass]"
/>
<view class="pi-count-down" :style="[customStyle]" :class="[customClass]">
<view
v-for="time in getShowTimes"
:key="time.key"
class="countdown-item"
:class="time.name"
:style="[time.name === 'time' ? timeStyle : separatorStyle]"
>
{{ time.value }}
</view>
</view>
</template>

<script>
import ValueSync from '../../mixin/value-sync'
import { getConfig } from '../../config'
const { countDwon } = getConfig()
const { countDown } = getConfig()
const TAG = 'PiCountDown'
Expand All @@ -26,21 +32,109 @@ export default {
customStyle: {
type: Object,
default() {
return countDwon.customStyle
return countDown.customStyle
}
},
// 自定义样式类,字符串形式('')
customClass: {
type: String,
default() {
return countDwon.customClass
return countDown.customClass
}
},
// 每一个项时间的自定义样式
timeStyle: {
type: Object,
default() {
return countDown.timeStyle
}
},
// 每一个项分隔符的自定义样式
separatorStyle: {
type: Object,
default() {
return countDown.separatorStyle
}
},
autoplay: {
type: Boolean,
default() {
return countDwon.autoplay
return countDown.autoplay
}
},
// 分隔符,colon为英文冒号,zh为中文
separator: {
type: String,
default() {
return countDown.separator
},
validator: function(value) {
return ['colon', 'zh'].includes(value)
}
},
// 是否显示天
showDay: {
type: Boolean,
default() {
return countDown.showDay
}
},
// 是否显示小时
showHour: {
type: Boolean,
default() {
return countDown.showHour
}
},
// 是否显示分钟
showMinute: {
type: Boolean,
default() {
return countDown.showMinute
}
},
// 是否显示秒
showSecond: {
type: Boolean,
default() {
return countDown.showSecond
}
}
},
data() {
return {
timer: null // 定时器
}
},
computed: {
showTime() {
return this.$pi.date.calcuLeftTime(this.val, this.showDay)
},
getShowTimes() {
const times = []
if (this.showDay) {
const separator = this.separator === 'colon' ? ':' : ''
times.push({ key: 'day-value', name: 'time', value: this.showTime.day })
times.push({ key: 'day-separator', name: 'separator', value: separator })
}
if (this.showHour) {
const separator = this.separator === 'colon' ? ':' : ''
times.push({ key: 'hour-value', name: 'time', value: this.showTime.hour })
times.push({ key: 'hour-separator', name: 'separator', value: separator })
}
if (this.showMinute) {
const separator = this.separator === 'colon' ? ':' : ''
times.push({ key: 'minute-value', name: 'time', value: this.showTime.minute })
times.push({ key: 'minute-separator', name: 'separator', value: separator })
}
if (this.showSecond) {
const separator = this.separator === 'colon' ? ':' : ''
times.push({ key: 'second-value', name: 'time', value: this.showTime.second })
this.separator === 'zh' &&
times.push({ key: 'second-separator', name: 'separator', value: separator })
}
return times
}
},
watch: {
Expand All @@ -53,7 +147,52 @@ export default {
}
},
methods: {
run() {}
run() {
// 避免可能出现的倒计时重叠情况
this.clearTimer()
if (this.timestamp <= 0) return
this.timer = setInterval(() => {
this.val--
if (this.val <= 0) {
return this.stop()
}
}, 1000)
},
// 停止倒计时
stop() {
this.clearTimer()
this.$emit('stop', {})
},
// 清除定时器
clearTimer() {
if (this.timer) {
// 清除定时器
clearInterval(this.timer)
this.timer = null
}
}
}
}
</script>

<style lang="scss" scoped>
.pi-count-down {
display: inline-block;
.countdown-item {
display: inline-block;
padding: 2rpx;
text-align: center;
white-space: nowrap;
border-radius: 6rpx;
// 欺骗浏览器使用gpu渲染
transform: translateZ(0);
&.time {
min-width: 44rpx;
min-height: 44rpx;
}
&.separator {
margin: 0 4rpx;
}
}
}
</style>
2 changes: 1 addition & 1 deletion components/pi-navbar/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ export default {
methods: {
syncPageRoute() {
if (this.showBack === '') {
/* eslint-disable */
/* eslint-disable */
const pages = getCurrentPages()
// 如果堆栈大于1表示打开了子页面,需要显示返回按钮
this.isShowBack = pages.length > 1
Expand Down
9 changes: 8 additions & 1 deletion config/countDown.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
export default {
customClass: '', // 自定义样式类,字符串形式('')
customStyle: {}, // 自定义样式,对象形式(默认值:{})
autoplay: true // 是否自动开始倒计时,如果为false,需手动调用开始方法
timeStyle: {}, // 每一个项时间的自定义样式,对象形式(默认值:{})
separatorStyle: {}, // 每一个项时间的自定义样式,对象形式(默认值:{})
autoplay: true, // 是否自动开始倒计时,如果为false,需手动调用开始方法
separator: 'colon', // 分隔符,colon为英文冒号,zh为中文
showDay: true, // 是否显示天
showHour: true, // 是否显示小时
showMinute: true, // 是否显示分钟
showSecond: true // 是否显示秒
}
25 changes: 25 additions & 0 deletions tools/date.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,28 @@ export const formatDate = (value = new Date(), fmt = 'yyyy-mm-dd') => {
}
return fmt
}

/**
* 计算剩余时间
* @param {*} timestamp 时间差
* @param {*} showDay 是否显示天数
*/
export const calcuLeftTime = (timestamp, showDay = true) => {
const defaultValue = [0, 0, 0, 0]
let [day, hour, minute, second] = defaultValue

if (timestamp <= 0) return defaultValue

day = Math.floor(timestamp / (60 * 60 * 24))
hour = Math.floor(timestamp / (60 * 60)) - day * 24
minute = Math.floor(timestamp / 60) - hour * 60 - day * 24 * 60
second = Math.floor(timestamp) - day * 24 * 60 * 60 - hour * 60 * 60 - minute * 60

day = day < 10 ? '0' + day : day
let formatHour = showDay ? hour : Math.floor(timestamp / (60 * 60))
formatHour = formatHour < 10 ? '0' + formatHour : formatHour
minute = minute < 10 ? '0' + minute : minute
second = second < 10 ? '0' + second : second

return { day, hour: formatHour, minute, second }
}

0 comments on commit 9540b6b

Please sign in to comment.