| <template> | 
|   <view class="tn-countdown-class tn-countdown"> | 
|     <view | 
|       v-if="showDays && (hideZeroDay || (!hideZeroDay && d != '00'))" | 
|       class="tn-countdown__item" | 
|       :class="[backgroundColorClass]" | 
|       :style="[itemStyle]" | 
|     > | 
|       <view class="tn-countdown__item__time" :class="[fontColorClass]" :style="[letterStyle]"> | 
|         {{ d }} | 
|       </view> | 
|     </view> | 
|     <view  | 
|       v-if="showHours && (hideZeroDay || (!hideZeroDay && d != '00'))" | 
|       class="tn-countdown__separator" | 
|       :style="{ | 
|         fontSize: separatorSize + 'rpx', | 
|         color: separatorColor, | 
|         paddingBottom: separator === 'en' ? '4rpx' : 0 | 
|       }" | 
|     > | 
|       {{ separator === 'en' ? ':' : '天'}} | 
|     </view> | 
|      | 
|     <view | 
|       v-if="showHours" | 
|       class="tn-countdown__item" | 
|       :class="[backgroundColorClass]" | 
|       :style="[itemStyle]" | 
|     > | 
|       <view class="tn-countdown__item__time" :class="[fontColorClass]" :style="[letterStyle]"> | 
|         {{ h }} | 
|       </view> | 
|     </view> | 
|     <view  | 
|       v-if="showMinutes" | 
|       class="tn-countdown__separator" | 
|       :style="{ | 
|         fontSize: separatorSize + 'rpx', | 
|         color: separatorColor, | 
|         paddingBottom: separator === 'en' ? '4rpx' : 0 | 
|       }" | 
|     > | 
|       {{ separator === 'en' ? ':' : '时'}} | 
|     </view> | 
|      | 
|     <view | 
|       v-if="showMinutes" | 
|       class="tn-countdown__item" | 
|       :class="[backgroundColorClass]" | 
|       :style="[itemStyle]" | 
|     > | 
|       <view class="tn-countdown__item__time" :class="[fontColorClass]" :style="[letterStyle]"> | 
|         {{ m }} | 
|       </view> | 
|     </view> | 
|     <view  | 
|       v-if="showSeconds" | 
|       class="tn-countdown__separator" | 
|       :style="{ | 
|         fontSize: separatorSize + 'rpx', | 
|         color: separatorColor, | 
|         paddingBottom: separator === 'en' ? '4rpx' : 0 | 
|       }" | 
|     > | 
|       {{ separator === 'en' ? ':' : '分'}} | 
|     </view> | 
|      | 
|     <view | 
|       v-if="showSeconds" | 
|       class="tn-countdown__item" | 
|       :class="[backgroundColorClass]" | 
|       :style="[itemStyle]" | 
|     > | 
|       <view class="tn-countdown__item__time" :class="[fontColorClass]" :style="[letterStyle]"> | 
|         {{ s }} | 
|       </view> | 
|     </view> | 
|     <view  | 
|       v-if="showSeconds && separator === 'cn'" | 
|       class="tn-countdown__separator" | 
|       :style="{ | 
|         fontSize: separatorSize + 'rpx', | 
|         color: separatorColor, | 
|         paddingBottom: separator === 'en' ? '4rpx' : 0 | 
|       }" | 
|     > | 
|       秒 | 
|     </view> | 
|   </view> | 
| </template> | 
|   | 
| <script> | 
|   import componentsColorMixin from '../../libs/mixin/components_color.js' | 
|   export default { | 
|     name: 'tn-count-down', | 
|     mixins: [componentsColorMixin], | 
|     props: { | 
|       // 倒计时时间,秒作为单位 | 
|       timestamp: { | 
|         type: Number, | 
|         default: 0 | 
|       }, | 
|       // 是否自动开始 | 
|       autoplay: { | 
|         type: Boolean, | 
|         default: true | 
|       }, | 
|       // 数字框高度 | 
|       height: { | 
|         type: [String, Number], | 
|         default: 'auto' | 
|       }, | 
|       // 分隔符类型 | 
|       // en -> 使用英文的冒号 cn -> 使用中文进行分割 | 
|       separator: { | 
|         type: String, | 
|         default: 'en' | 
|       }, | 
|       // 分割符大小 | 
|       separatorSize: { | 
|         type: Number, | 
|         default: 30 | 
|       }, | 
|       // 分隔符颜色 | 
|       separatorColor: { | 
|         type: String, | 
|         default: '#080808' | 
|       }, | 
|       // 是否显示边框 | 
|       showBorder: { | 
|         type: Boolean, | 
|         default: false | 
|       }, | 
|       // 边框颜色 | 
|       borderColor: { | 
|         type: String, | 
|         default: '#080808' | 
|       }, | 
|       // 是否显示秒 | 
|       showSeconds: { | 
|         type: Boolean, | 
|         default: true | 
|       }, | 
|       // 是否显示分 | 
|       showMinutes: { | 
|         type: Boolean, | 
|         default: true | 
|       }, | 
|       // 是否显示时 | 
|       showHours: { | 
|         type: Boolean, | 
|         default: true | 
|       }, | 
|       // 是否显示天 | 
|       showDays: { | 
|         type: Boolean, | 
|         default: true | 
|       }, | 
|       // 如果当天的部分为0时,是否隐藏不显示 | 
|       hideZeroDay: { | 
|         type: Boolean, | 
|         default: false | 
|       } | 
|     }, | 
|     computed: { | 
|       // 倒计时item的样式 | 
|       itemStyle() { | 
|         let style = {} | 
|         if (this.height) { | 
|           style.height = this.$t.string.getLengthUnitValue(this.height) | 
|           style.width = style.height | 
|         } | 
|         if (this.showBorder) { | 
|           style.borderStyle = 'solid' | 
|           style.borderColor = this.borderColor | 
|           style.borderWidth = '1rpx' | 
|         } | 
|         style.backgroundColor = this.backgroundColorStyle || '#FFFFFF' | 
|         return style | 
|       }, | 
|       // 倒计时数字样式 | 
|       letterStyle() { | 
|         let style = {} | 
|         style.fontSize = this.fontSizeStyle || '30rpx' | 
|         style.color = this.fontColorStyle || '#080808' | 
|         return style | 
|       } | 
|     }, | 
|     data() { | 
|       return { | 
|         d: '00', | 
|         h: '00', | 
|         m: '00', | 
|         s: '00', | 
|         // 定时器 | 
|         timer: null, | 
|         // 记录倒计过程中变化的秒数 | 
|         seconds: 0 | 
|       } | 
|     }, | 
|     watch: { | 
|       // 监听时间戳变化 | 
|       timestamp(value) { | 
|         this.clearTimer() | 
|         this.start() | 
|       } | 
|     }, | 
|     mounted() { | 
|       // 如果时自动倒计时,加载完成开始计时 | 
|       this.autoplay && this.timestamp && this.start() | 
|     }, | 
|     beforeDestroy() { | 
|       this.clearTimer() | 
|     }, | 
|     methods: { | 
|       // 开始倒计时 | 
|       start() { | 
|         // 避免可能出现的倒计时重叠情况 | 
|         this.clearTimer() | 
|         if (this.timestamp <= 0) return | 
|         this.seconds = Number(this.timestamp) | 
|         this.formatTime(this.seconds) | 
|         this.timer = setInterval(() => { | 
|           this.seconds-- | 
|           // 发出change事件 | 
|           this.$emit('change', this.seconds) | 
|           if (this.seconds < 0) { | 
|             return this.end() | 
|           } | 
|           this.formatTime(this.seconds) | 
|         }, 1000) | 
|       }, | 
|       // 格式化时间 | 
|       formatTime(seconds) { | 
|         // 小于等于0的话,结束倒计时 | 
|         seconds <= 0 && this.end() | 
|         let [day, hour, minute, second] = [0, 0, 0, 0] | 
|         day = Math.floor(seconds / (60 * 60 * 24)) | 
|         // 如果不显示天,则将天对应的小时计入到小时中 | 
|         // 先把当前的hour计算出来供分和秒使用 | 
|         hour = Math.floor(seconds / (60 * 60)) - (day * 24) | 
|         let showHour = null | 
|         if (this.showDays) { | 
|           showHour = hour | 
|         } else { | 
|           // 将天数对应的小时加入到时中进行显示 | 
|           showHour = Math.floor(seconds / (60 * 60)) | 
|         } | 
|         minute = Math.floor(seconds / 60) - (hour * 60) - (day * 24 * 60) | 
|         second = Math.floor(seconds) - (minute * 60) - (hour * 60 * 60) - (day * 24 * 60 * 60) | 
|         // 如果小于0在前面进行补0操作 | 
|         showHour = this.$t.number.formatNumberAddZero(showHour) | 
|         minute = this.$t.number.formatNumberAddZero(minute) | 
|         second = this.$t.number.formatNumberAddZero(second) | 
|         day = this.$t.number.formatNumberAddZero(day) | 
|          | 
|         this.d = day | 
|         this.h = showHour | 
|         this.m = minute | 
|         this.s = second | 
|       }, | 
|       // 倒计时结束 | 
|       end() { | 
|         this.clearTimer() | 
|         this.$emit('end') | 
|       }, | 
|       // 清除倒计时 | 
|       clearTimer() { | 
|         if (this.timer !== null) { | 
|           clearInterval(this.timer) | 
|           this.timer = null | 
|         } | 
|       } | 
|     } | 
|   } | 
| </script> | 
|   | 
| <style lang="scss" scoped> | 
|    | 
|   .tn-countdown { | 
|     /* #ifndef APP-NVUE */ | 
|     display: inline-flex; | 
|     /* #endif */ | 
|     align-items: center; | 
|      | 
|     &__item { | 
|       box-sizing: content-box; | 
|       display: flex; | 
|       flex-direction: row; | 
|       align-items: center; | 
|       justify-content: center; | 
|       padding: 2rpx; | 
|       border-radius: 6rpx; | 
|       white-space: nowrap; | 
|       transform: translateZ(0); | 
|        | 
|       &__time { | 
|         margin: 0; | 
|         padding: 0; | 
|         line-height: 1; | 
|       } | 
|     } | 
|      | 
|     &__separator { | 
|       display: flex; | 
|       flex-direction: row; | 
|       align-items: center; | 
|       justify-content: center; | 
|       padding: 0 5rpx; | 
|       line-height: 1; | 
|     } | 
|   } | 
| </style> |