| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271 | <template>	<view class="uni-countdown">		<text v-if="showDay" :style="[timeStyle]" class="uni-countdown__number">{{ d }}</text>		<text v-if="showDay" :style="[splitorStyle]" class="uni-countdown__splitor">{{dayText}}</text>		<text :style="[timeStyle]" class="uni-countdown__number">{{ h }}</text>		<text :style="[splitorStyle]" class="uni-countdown__splitor">{{ showColon ? ':' : hourText }}</text>		<text :style="[timeStyle]" class="uni-countdown__number">{{ i }}</text>		<text :style="[splitorStyle]" class="uni-countdown__splitor">{{ showColon ? ':' : minuteText }}</text>		<text :style="[timeStyle]" class="uni-countdown__number">{{ s }}</text>		<text v-if="!showColon" :style="[splitorStyle]" class="uni-countdown__splitor">{{secondText}}</text>	</view></template><script>	import {		initVueI18n	} from '@dcloudio/uni-i18n'	import messages from './i18n/index.js'	const {		t	} = initVueI18n(messages)	/**	 * Countdown 倒计时	 * @description 倒计时组件	 * @tutorial https://ext.dcloud.net.cn/plugin?id=25	 * @property {String} backgroundColor 背景色	 * @property {String} color 文字颜色	 * @property {Number} day 天数	 * @property {Number} hour 小时	 * @property {Number} minute 分钟	 * @property {Number} second 秒	 * @property {Number} timestamp 时间戳	 * @property {Boolean} showDay = [true|false] 是否显示天数	 * @property {Boolean} show-colon = [true|false] 是否以冒号为分隔符	 * @property {String} splitorColor 分割符号颜色	 * @event {Function} timeup 倒计时时间到触发事件	 * @example <uni-countdown :day="1" :hour="1" :minute="12" :second="40"></uni-countdown>	 */	export default {		name: 'UniCountdown',		emits: ['timeup'],		props: {			showDay: {				type: Boolean,				default: true			},			showColon: {				type: Boolean,				default: true			},			start: {				type: Boolean,				default: true			},			backgroundColor: {				type: String,				default: ''			},			color: {				type: String,				default: '#333'			},			fontSize: {				type: Number,				default: 14			},			splitorColor: {				type: String,				default: '#333'			},			day: {				type: Number,				default: 0			},			hour: {				type: Number,				default: 0			},			minute: {				type: Number,				default: 0			},			second: {				type: Number,				default: 0			},			timestamp: {				type: Number,				default: 0			}		},		data() {			return {				timer: null,				syncFlag: false,				d: '00',				h: '00',				i: '00',				s: '00',				leftTime: 0,				seconds: 0			}		},		computed: {			dayText() {				return t("uni-countdown.day")			},			hourText(val) {				return t("uni-countdown.h")			},			minuteText(val) {				return t("uni-countdown.m")			},			secondText(val) {				return t("uni-countdown.s")			},			timeStyle() {				const {					color,					backgroundColor,					fontSize				} = this				return {					color,					backgroundColor,					fontSize: `${fontSize}px`,					width: `${fontSize * 22 / 14}px`, // 按字体大小为 14px 时的比例缩放 					lineHeight: `${fontSize * 20 / 14}px`,					borderRadius: `${fontSize * 3 / 14}px`,				}			},			splitorStyle() {				const { splitorColor, fontSize, backgroundColor } = this				return {					color: splitorColor,					fontSize: `${fontSize * 12 / 14}px`,					margin: backgroundColor ? `${fontSize * 4 / 14}px` : ''				}			}		},		watch: {			day(val) {				this.changeFlag()			},			hour(val) {				this.changeFlag()			},			minute(val) {				this.changeFlag()			},			second(val) {				this.changeFlag()			},			start: {				immediate: true,				handler(newVal, oldVal) {					if (newVal) {						this.startData();					} else {						if (!oldVal) return						clearInterval(this.timer)					}				}			}		},		created: function(e) {			this.seconds = this.toSeconds(this.timestamp, this.day, this.hour, this.minute, this.second)			this.countDown()		},		// #ifndef VUE3		destroyed() {			clearInterval(this.timer)		},		// #endif		// #ifdef VUE3		unmounted() {			clearInterval(this.timer)		},		// #endif		methods: {			toSeconds(timestamp, day, hours, minutes, seconds) {				if (timestamp) {					return timestamp - parseInt(new Date().getTime() / 1000, 10)				}				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.timestamp, this.day, this.hour, this.minute, this.second)				if (this.seconds <= 0) {					this.seconds = this.toSeconds(0, 0, 0, 0, 0)					this.countDown()					return				}				clearInterval(this.timer)				this.countDown()				this.timer = setInterval(() => {					this.seconds--					if (this.seconds < 0) {						this.timeUp()						return					}					this.countDown()				}, 1000)			},			update(){				this.startData();			},			changeFlag() {				if (!this.syncFlag) {					this.seconds = this.toSeconds(this.timestamp, this.day, this.hour, this.minute, this.second)					this.startData();					this.syncFlag = true;				}			}		}	}</script><style lang="scss" scoped>	$font-size: 14px;	.uni-countdown {		display: flex;		flex-direction: row;		justify-content: flex-start;		align-items: center;		&__splitor {			margin: 0 2px;			font-size: $font-size;			color: #333;		}		&__number {			border-radius: 3px;			text-align: center;			font-size: $font-size;		}	}</style>
 |