From f26f29d84e0a68831a6af14dab3eec5500496d2e Mon Sep 17 00:00:00 2001 From: spring <2396852758@qq.com> Date: 星期三, 28 五月 2025 16:48:52 +0800 Subject: [PATCH] 初始化项目 --- uview-ui/components/u-count-down/u-count-down.vue | 318 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 318 insertions(+), 0 deletions(-) diff --git a/uview-ui/components/u-count-down/u-count-down.vue b/uview-ui/components/u-count-down/u-count-down.vue new file mode 100644 index 0000000..7285d67 --- /dev/null +++ b/uview-ui/components/u-count-down/u-count-down.vue @@ -0,0 +1,318 @@ +<template> + <view class="u-countdown"> + <view class="u-countdown-item" :style="[itemStyle]" v-if="showDays && (hideZeroDay || (!hideZeroDay && d != '00'))"> + <view class="u-countdown-time" :style="[letterStyle]"> + {{ d }} + </view> + </view> + <view + class="u-countdown-colon" + :style="{fontSize: separatorSize + 'rpx', color: separatorColor, paddingBottom: separator == 'colon' ? '4rpx' : 0}" + v-if="showDays && (hideZeroDay || (!hideZeroDay && d != '00'))" + > + {{ separator == 'colon' ? ':' : '澶�' }} + </view> + <view class="u-countdown-item" :style="[itemStyle]" v-if="showHours"> + <view class="u-countdown-time" :style="{ fontSize: fontSize + 'rpx', color: color}"> + {{ h }} + </view> + </view> + <view + class="u-countdown-colon" + :style="{fontSize: separatorSize + 'rpx', color: separatorColor, paddingBottom: separator == 'colon' ? '4rpx' : 0}" + v-if="showHours" + > + {{ separator == 'colon' ? ':' : '鏃�' }} + </view> + <view class="u-countdown-item" :style="[itemStyle]" v-if="showMinutes"> + <view class="u-countdown-time" :style="{ fontSize: fontSize + 'rpx', color: color}"> + {{ i }} + </view> + </view> + <view + class="u-countdown-colon" + :style="{fontSize: separatorSize + 'rpx', color: separatorColor, paddingBottom: separator == 'colon' ? '4rpx' : 0}" + v-if="showMinutes" + > + {{ separator == 'colon' ? ':' : '鍒�' }} + </view> + <view class="u-countdown-item" :style="[itemStyle]" v-if="showSeconds"> + <view class="u-countdown-time" :style="{ fontSize: fontSize + 'rpx', color: color}"> + {{ s }} + </view> + </view> + <view + class="u-countdown-colon" + :style="{fontSize: separatorSize + 'rpx', color: separatorColor, paddingBottom: separator == 'colon' ? '4rpx' : 0}" + v-if="showSeconds && separator == 'zh'" + > + 绉� + </view> + </view> +</template> + +<script> +/** + * countDown 鍊掕鏃� + * @description 璇ョ粍浠朵竴鑸娇鐢ㄤ簬鏌愪釜娲诲姩鐨勬埅姝㈡椂闂翠笂锛岄�氳繃鏁板瓧鐨勫彉鍖栵紝缁欑敤鎴锋槑纭殑鏃堕棿鎰熷彈锛屾彁绀虹敤鎴疯繘琛屾煇涓�涓涓烘搷浣溿�� + * @tutorial https://www.uviewui.com/components/countDown.html + * @property {String Number} timestamp 鍊掕鏃讹紝鍗曚綅涓虹 + * @property {Boolean} autoplay 鏄惁鑷姩寮�濮嬪�掕鏃讹紝濡傛灉涓篺alse锛岄渶鎵嬪姩璋冪敤寮�濮嬫柟娉曘�傝瀹樼綉璇存槑锛堥粯璁rue锛� + * @property {String} separator 鍒嗛殧绗︼紝colon涓鸿嫳鏂囧啋鍙凤紝zh涓轰腑鏂囷紙榛樿colon锛� + * @property {String Number} separator-size 鍒嗛殧绗︾殑瀛椾綋澶у皬锛屽崟浣峳px锛堥粯璁�30锛� + * @property {String} separator-color 鍒嗛殧绗︾殑棰滆壊锛堥粯璁�#303133锛� + * @property {String Number} font-size 鍊掕鏃跺瓧浣撳ぇ灏忥紝鍗曚綅rpx锛堥粯璁�30锛� + * @property {Boolean} show-border 鏄惁鏄剧ず鍊掕鏃舵暟瀛楃殑杈规锛堥粯璁alse锛� + * @property {Boolean} hide-zero-day 褰�"澶�"鐨勯儴鍒嗕负0鏃讹紝闅愯棌璇ュ瓧娈� 锛堥粯璁rue锛� + * @property {String} border-color 鏁板瓧杈规鐨勯鑹诧紙榛樿#303133锛� + * @property {String} bg-color 鍊掕鏃舵暟瀛楃殑鑳屾櫙棰滆壊锛堥粯璁�#ffffff锛� + * @property {String} color 鍊掕鏃舵暟瀛楃殑棰滆壊锛堥粯璁�#303133锛� + * @property {String} height 鏁板瓧楂樺害鍊�(瀹藉害绛夊悓姝ゅ��)锛岃缃竟妗嗘椂鐪嬫儏鍐垫槸鍚﹂渶瑕佽缃鍊硷紝鍗曚綅rpx锛堥粯璁uto锛� + * @property {Boolean} show-days 鏄惁鏄剧ず鍊掕鏃剁殑"澶�"閮ㄥ垎锛堥粯璁rue锛� + * @property {Boolean} show-hours 鏄惁鏄剧ず鍊掕鏃剁殑"鏃�"閮ㄥ垎锛堥粯璁rue锛� + * @property {Boolean} show-minutes 鏄惁鏄剧ず鍊掕鏃剁殑"鍒�"閮ㄥ垎锛堥粯璁rue锛� + * @property {Boolean} show-seconds 鏄惁鏄剧ず鍊掕鏃剁殑"绉�"閮ㄥ垎锛堥粯璁rue锛� + * @event {Function} end 鍊掕鏃剁粨鏉� + * @event {Function} change 姣忕瑙﹀彂涓�娆★紝鍥炶皟涓哄綋鍓嶅墿浣欑殑鍊掕绉掓暟 + * @example <u-count-down ref="uCountDown" :timestamp="86400" :autoplay="false"></u-count-down> + */ +export default { + name: 'u-count-down', + props: { + // 鍊掕鏃剁殑鏃堕棿锛岀涓哄崟浣� + timestamp: { + type: [Number, String], + default: 0 + }, + // 鏄惁鑷姩寮�濮嬪�掕鏃� + autoplay: { + type: Boolean, + default: true + }, + // 鐢ㄨ嫳鏂囧啋鍙�(colon)鎴栬�呬腑鏂�(zh)褰撳仛鍒嗛殧绗︼紝false鐨勬椂鍊欎负涓枃锛屽锛�"11:22"鎴�"11鏃�22绉�" + separator: { + type: String, + default: 'colon' + }, + // 鍒嗛殧绗︾殑澶у皬锛屽崟浣峳px + separatorSize: { + type: [Number, String], + default: 30 + }, + // 鍒嗛殧绗﹂鑹� + separatorColor: { + type: String, + default: "#303133" + }, + // 瀛椾綋棰滆壊 + color: { + type: String, + default: '#303133' + }, + // 瀛椾綋澶у皬锛屽崟浣峳px + fontSize: { + type: [Number, String], + default: 30 + }, + // 鑳屾櫙棰滆壊 + bgColor: { + type: String, + default: '#fff' + }, + // 鏁板瓧妗嗛珮搴︼紝鍗曚綅rpx + height: { + type: [Number, String], + default: 'auto' + }, + // 鏄惁鏄剧ず鏁板瓧妗� + showBorder: { + type: Boolean, + default: false + }, + // 杈规棰滆壊 + borderColor: { + type: String, + default: '#303133' + }, + // 鏄惁鏄剧ず绉� + 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 + } + }, + watch: { + // 鐩戝惉鏃堕棿鎴崇殑鍙樺寲 + timestamp(newVal, oldVal) { + // 濡傛灉鍊掕鏃堕棿鍙戠敓鍙樺寲锛屾竻闄ゅ畾鏃跺櫒锛岄噸鏂板紑濮嬪�掕鏃� + this.clearTimer(); + this.start(); + } + }, + data() { + return { + d: '00', // 澶╃殑榛樿鍊� + h: '00', // 灏忔椂鐨勯粯璁ゅ�� + i: '00', // 鍒嗛挓鐨勯粯璁ゅ�� + s: '00', // 绉掔殑榛樿鍊� + timer: null ,// 瀹氭椂鍣� + seconds: 0, // 璁板綍涓嶅仠鍊掕杩囩▼涓彉鍖栫殑绉掓暟 + }; + }, + computed: { + // 鍊掕鏃秈tem鐨勬牱寮忥紝item涓哄垎鍒殑鏃跺垎绉掗儴鍒嗙殑鏁板瓧 + itemStyle() { + let style = {}; + if(this.height) { + style.height = this.height + 'rpx'; + style.width = this.height + 'rpx'; + } + if(this.showBorder) { + style.borderStyle = 'solid'; + style.borderColor = this.borderColor; + style.borderWidth = '1px'; + } + if(this.bgColor) { + style.backgroundColor = this.bgColor; + } + return style; + }, + // 鍊掕鏃舵暟瀛楃殑鏍峰紡 + letterStyle() { + let style = {}; + if(this.fontSize) style.fontSize = this.fontSize + 'rpx'; + if(this.color) style.color = this.color; + return style; + } + }, + mounted() { + // 濡傛灉鑷姩鍊掕鏃� + this.autoplay && this.timestamp && this.start(); + }, + 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; + // showHour涓洪渶瑕佹樉绀虹殑灏忔椂 + 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) - day * 24 * 60 * 60 - hour * 60 * 60 - minute * 60; + // 濡傛灉灏忎簬10锛屽湪鍓嶉潰琛ヤ笂涓�涓�"0" + showHour = showHour < 10 ? '0' + showHour : showHour; + minute = minute < 10 ? '0' + minute : minute; + second = second < 10 ? '0' + second : second; + day = day < 10 ? '0' + day : day; + this.d = day; + this.h = showHour; + this.i = minute; + this.s = second; + }, + // 鍋滄鍊掕鏃� + end() { + this.clearTimer(); + this.$emit('end', {}); + }, + // 娓呴櫎瀹氭椂鍣� + clearTimer() { + if(this.timer) { + // 娓呴櫎瀹氭椂鍣� + clearInterval(this.timer); + this.timer = null; + } + } + }, + beforeDestroy() { + clearInterval(this.timer); + this.timer = null; + } +}; +</script> + +<style scoped lang="scss"> + @import "../../libs/css/style.components.scss"; + + .u-countdown { + /* #ifndef APP-NVUE */ + display: inline-flex; + /* #endif */ + align-items: center; + } + + .u-countdown-item { + @include vue-flex; + align-items: center; + justify-content: center; + padding: 2rpx; + border-radius: 6rpx; + white-space: nowrap; + transform: translateZ(0); + } + + .u-countdown-time { + margin: 0; + padding: 0; + line-height: 1; + } + + .u-countdown-colon { + @include vue-flex; + justify-content: center; + padding: 0 5rpx; + line-height: 1; + align-items: center; + padding-bottom: 4rpx; + } + + .u-countdown-scale { + transform: scale(0.9); + transform-origin: center center; + } +</style> -- Gitblit v1.9.3