¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <view class="u-count-down"> |
| | | <slot> |
| | | <text class="u-count-down__text">{{ formattedTime }}</text> |
| | | </slot> |
| | | </view> |
| | | </template> |
| | | |
| | | <script> |
| | | import props from './props.js'; |
| | | import { |
| | | isSameSecond, |
| | | parseFormat, |
| | | parseTimeData |
| | | } from './utils'; |
| | | /** |
| | | * u-count-down åè®¡æ¶ |
| | | * @description 该ç»ä»¶ä¸è¬ä½¿ç¨äºæä¸ªæ´»å¨çæªæ¢æ¶é´ä¸ï¼éè¿æ°åçååï¼ç»ç¨æ·æç¡®çæ¶é´æåï¼æç¤ºç¨æ·è¿è¡æä¸ä¸ªè¡ä¸ºæä½ã |
| | | * @tutorial https://uviewui.com/components/countDown.html |
| | | * @property {String | Number} time åè®¡æ¶æ¶é¿ï¼åä½ms ï¼é»è®¤ 0 ï¼ |
| | | * @property {String} format æ¶é´æ ¼å¼ï¼DD-æ¥ï¼HH-æ¶ï¼mm-åï¼ss-ç§ï¼SSS-æ¯«ç§ ï¼é»è®¤ 'HH:mm:ss' ï¼ |
| | | * @property {Boolean} autoStart æ¯å¦èªå¨å¼å§åè®¡æ¶ ï¼é»è®¤ true ï¼ |
| | | * @property {Boolean} millisecond æ¯å¦å±ç¤ºæ¯«ç§åè®¡æ¶ ï¼é»è®¤ false ï¼ |
| | | * @event {Function} finish å计æ¶ç»ææ¶è§¦å |
| | | * @event {Function} change å计æ¶ååæ¶è§¦å |
| | | * @event {Function} start å¼å§åè®¡æ¶ |
| | | * @event {Function} pause æååè®¡æ¶ |
| | | * @event {Function} reset é设å计æ¶ï¼è¥ auto-start 为 trueï¼é设åä¼èªå¨å¼å§åè®¡æ¶ |
| | | * @example <u-count-down :time="time"></u-count-down> |
| | | */ |
| | | export default { |
| | | name: 'u-count-down', |
| | | mixins: [uni.$u.mpMixin, uni.$u.mixin, props], |
| | | data() { |
| | | return { |
| | | timer: null, |
| | | // ååä½(å¤©ï¼æ¶ï¼åç)å©ä½æ¶é´ |
| | | timeData: parseTimeData(0), |
| | | // æ ¼å¼ååçæ¶é´ï¼å¦"03:23:21" |
| | | formattedTime: '0', |
| | | // åè®¡æ¶æ¯å¦æ£å¨è¿è¡ä¸ |
| | | runing: false, |
| | | endTime: 0, // ç»æçæ¯«ç§æ¶é´æ³ |
| | | remainTime: 0, // å©ä½çæ¯«ç§æ¶é´ |
| | | } |
| | | }, |
| | | watch: { |
| | | time(n) { |
| | | this.reset() |
| | | } |
| | | }, |
| | | mounted() { |
| | | this.init() |
| | | }, |
| | | methods: { |
| | | init() { |
| | | this.reset() |
| | | }, |
| | | // å¼å§åè®¡æ¶ |
| | | start() { |
| | | if (this.runing) return |
| | | // æ è¯ä¸ºè¿è¡ä¸ |
| | | this.runing = true |
| | | // ç»ææ¶é´æ³ = æ¤å»æ¶é´æ³ + å©ä½çæ¶é´ |
| | | this.endTime = Date.now() + this.remainTime |
| | | this.toTick() |
| | | }, |
| | | // æ ¹æ®æ¯å¦å±ç¤ºæ¯«ç§ï¼æ§è¡ä¸åæä½å½æ° |
| | | toTick() { |
| | | if (this.millisecond) { |
| | | this.microTick() |
| | | } else { |
| | | this.macroTick() |
| | | } |
| | | }, |
| | | macroTick() { |
| | | this.clearTimeout() |
| | | // æ¯éä¸å®æ¶é´ï¼æ´æ°ä¸é宿¶å¨çå¼ |
| | | // åæ¶æ¤å®æ¶å¨çä½ç¨ä¹è½å¸¦æ¥æ¯«ç§çº§çæ´æ° |
| | | this.timer = setTimeout(() => { |
| | | // è·åå©ä½æ¶é´ |
| | | const remain = this.getRemainTime() |
| | | // é设å©ä½æ¶é´ |
| | | if (!isSameSecond(remain, this.remainTime) || remain === 0) { |
| | | this.setRemainTime(remain) |
| | | } |
| | | // 妿å©ä½æ¶é´ä¸ä¸º0ï¼åç»§ç»æ£æ¥æ´æ°åè®¡æ¶ |
| | | if (this.remainTime !== 0) { |
| | | this.macroTick() |
| | | } |
| | | }, 30) |
| | | }, |
| | | microTick() { |
| | | this.clearTimeout() |
| | | this.timer = setTimeout(() => { |
| | | this.setRemainTime(this.getRemainTime()) |
| | | if (this.remainTime !== 0) { |
| | | this.microTick() |
| | | } |
| | | }, 50) |
| | | }, |
| | | // è·åå©ä½çæ¶é´ |
| | | getRemainTime() { |
| | | // åæå¤§å¼ï¼é²æ¢åºç°å°äº0çå©ä½æ¶é´å¼ |
| | | return Math.max(this.endTime - Date.now(), 0) |
| | | }, |
| | | // 设置å©ä½çæ¶é´ |
| | | setRemainTime(remain) { |
| | | this.remainTime = remain |
| | | // æ ¹æ®å©ä½çæ¯«ç§æ¶é´ï¼å¾åºè¯¥æå¤©ï¼å°æ¶ï¼åéççå¼ï¼è¿åä¸ä¸ªå¯¹è±¡ |
| | | const timeData = parseTimeData(remain) |
| | | this.$emit('change', timeData) |
| | | // å¾åºæ ¼å¼ååçæ¶é´ |
| | | this.formattedTime = parseFormat(this.format, timeData) |
| | | // 妿æ¶é´å·²å°ï¼åæ¢åè®¡æ¶ |
| | | if (remain <= 0) { |
| | | this.pause() |
| | | this.$emit('finish') |
| | | } |
| | | }, |
| | | // éç½®åè®¡æ¶ |
| | | reset() { |
| | | this.pause() |
| | | this.remainTime = this.time |
| | | this.setRemainTime(this.remainTime) |
| | | if (this.autoStart) { |
| | | this.start() |
| | | } |
| | | }, |
| | | // æååè®¡æ¶ |
| | | pause() { |
| | | this.runing = false; |
| | | this.clearTimeout() |
| | | }, |
| | | // æ¸
ç©ºå®æ¶å¨ |
| | | clearTimeout() { |
| | | clearTimeout(this.timer) |
| | | this.timer = null |
| | | } |
| | | }, |
| | | beforeDestroy() { |
| | | this.clearTimeout() |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style |
| | | lang="scss" |
| | | scoped |
| | | > |
| | | @import "../../libs/css/components.scss"; |
| | | $u-count-down-text-color:$u-content-color !default; |
| | | $u-count-down-text-font-size:15px !default; |
| | | $u-count-down-text-line-height:22px !default; |
| | | |
| | | .u-count-down { |
| | | &__text { |
| | | color: $u-count-down-text-color; |
| | | font-size: $u-count-down-text-font-size; |
| | | line-height: $u-count-down-text-line-height; |
| | | } |
| | | } |
| | | </style> |