适用范围:支付宝,淘宝小程序
效果:
组件目录结构:
详情:
index.axml
<!-- [{"value":["3","5"],"style":"","isTime":true},{"value":"秒","style":""}] --> <view class="countdown-main-wrapper"> <block a:for="{{parsedTime}}"> <view style="{{item.style}}"> <block a:if="{{item && item.value && item.value[0]}}"> <!-- render time, eg. {"value":["3","5"],"style":"","isTime":true} --> <block a:if="{{item.isTime}}" > <block a:for="{{item.value}}" a:for-item="time" a:for-index="idx"> <!-- set style for second --> <text a:if="{{idx == item.value.length - 1 && index == parsedTime.length - 2}}" style="{{secondStyle || timeStyle}}">{{time}}</text> <text a:else style="{{timeStyle}}">{{time}}</text> </block> </block> <!-- render text, eg, {"value":"秒","style":""} --> <text a:else style="{{textStyle}}" class="rax-countdown-main-wrapper-colon">{{item.value[0]}}</text> </block> </view> </block> </view>
index.acss
.countdown-main-wrapper { display: flex; flex-direction: row; align-items: center; } .countdown-main-wrapper view:nth-child(2n-1)::after{ //冒号样式 display:flex; justify-content: center; align-items: center; content:':'; color:#3A3A3A; font-size:16rpx; font-family: PingFangSC-Medium; margin-top: -2rpx; } .countdown-main-wrapper view:nth-child(2n){ // 数字样式 font-size:16rpx; color:#3A3A3A; font-family: PingFangSC-Medium; border-radius:3rpx; padding:0; background-color: transparent; } .countdown-main-wrapper view:nth-child(1)::after{ content: ''; } .countdown-main-wrapper view:last-child::after{ content: ''; }
index.js
"use strict"; var _utils = require("./utils"); Component({ data: { count: 0 }, props: { timeRemaining: 0, interval: 1000, timeWrapStyle: '', textStyle: '', timeStyle: '', secondStyle: '', tpl: '{d}天{h}时{m}分{s}秒', onFormatFunc: null, onTick: null, onComplete: null }, onInit: function () { this.setTimes(); }, didUnmount: function () { if (this.counter) clearInterval(this.counter); }, methods: { setTimes() { var _this = this; var funcToExecute = this.props.onFormatFunc && typeof this.props.onFormatFunc === 'function' ? this.props.onFormatFunc : this.msToTime; this.funcToExecute = funcToExecute.bind(this); this.counter = setInterval(function () { _this.funcToExecute(); }, this.props.interval); }, msToTime: function msToTime() { var _this2 = this; var count = this.data.count; var timeDuration = (this.data.leftTime || this.props.timeRemaining) - count * this.props.interval; this.setData({ count: count + 1 }); if (!timeDuration || timeDuration <= 0) { if (this.counter) clearInterval(this.counter); } // parameter type of `parseInt` is 'string', so need to convert time to string first. let days = parseInt((timeDuration / (1000 * 60 * 60 * 24)).toString()); const oneSeconds = 1000; const oneMinutes = oneSeconds * 60; const oneHours = oneMinutes * 60; // 计算相差小时数 let hours = Math.floor(timeDuration / oneHours); // 计算相差分钟数 let minutes = Math.floor((timeDuration % oneHours) / oneMinutes); // 计算相差秒数 let seconds = Math.floor((timeDuration % oneMinutes) / oneSeconds); var timeType = { 'd': days < 10 ? '0' + days : days + '', 'h': hours < 10 ? '0' + hours : hours + '', 'm': minutes < 10 ? '0' + minutes : minutes + '', 's': seconds < 10 ? '0' + seconds : seconds + '' }; // format time var tpl = this.props.tpl || _utils.DEFAULT_TPL; var rule = new RegExp('\{[d,h,m,s]\}', 'g'); // used to matched all template item, which includes 'd', 'h', 'm' and 's'. var matchlist = []; var tmp = null; var _this$props = this.props, textStyle = _this$props.textStyle, timeWrapStyle = _this$props.timeWrapStyle; while ((tmp = rule.exec(tpl)) !== null) { matchlist.push(tmp.index, tmp.index); } if (matchlist.length !== 0) { // used to detect the last element matchlist.push(-1); } var lastPlaintextIndex = 0; var parsedTime = matchlist.map(function (val, index) { if (val === -1) { // don't forget the potential plain text after last matched item var lastPlaintext = tpl.slice(lastPlaintextIndex); return { value: lastPlaintext, style: textStyle }; } var matchedCharacter = tpl[val + 1]; switch (matchedCharacter) { case 'd': case 'h': case 'm': case 's': if (index % 2 === 0) { // insert plain text before current matched item return { value: tpl.slice(lastPlaintextIndex, val), style: textStyle }; } else { // replace current matched item to realtime string lastPlaintextIndex = val + 3; return { value: _this2.splitTime(timeType[matchedCharacter]), style: timeWrapStyle, isTime: true }; } default: return null; } }); parsedTime = parsedTime.filter(function (item) { return item; }); // check if the onTick function needs to be called var callOnTick = this.props.onTick && typeof this.props.onTick === 'function'; this.setData({ parsedTime: parsedTime }, callOnTick ? this.props.onTick : null); // check if onComplete function needs to be called if (timeDuration <= 0 && this.props.onComplete && typeof this.props.onComplete === 'function') { this.props.onComplete(); } }, splitTime: function splitTime(time) { if (time === void 0) { time = '00'; } return time.split(''); } } });
index.json
{ "component": true }
utils.js
"use strict"; exports.__esModule = true; exports.DEFAULT_TPL = void 0; var DEFAULT_TPL = '{d}天{h}时{m}分{s}秒'; exports.DEFAULT_TPL = DEFAULT_TPL;
用法:
<count-down timeRemaining="{{123456}}" tpl='{h}{m}{s}' />
标签:count,countdown,封装,wrapper,倒计时,var,props,组件,main From: https://www.cnblogs.com/yujiawen/p/17337993.html