101 lines
2.6 KiB
JavaScript
101 lines
2.6 KiB
JavaScript
import { VantComponent } from '../common/component';
|
|
import { isSameSecond, parseFormat, parseTimeData } from './utils';
|
|
function simpleTick(fn) {
|
|
return setTimeout(fn, 30);
|
|
}
|
|
VantComponent({
|
|
props: {
|
|
useSlot: Boolean,
|
|
millisecond: Boolean,
|
|
time: {
|
|
type: Number,
|
|
observer: 'reset'
|
|
},
|
|
format: {
|
|
type: String,
|
|
value: 'HH:mm:ss'
|
|
},
|
|
autoStart: {
|
|
type: Boolean,
|
|
value: true
|
|
}
|
|
},
|
|
data: {
|
|
timeData: parseTimeData(0),
|
|
formattedTime: '0'
|
|
},
|
|
destroyed() {
|
|
clearTimeout(this.tid);
|
|
this.tid = null;
|
|
},
|
|
methods: {
|
|
// 开始
|
|
start() {
|
|
if (this.counting) {
|
|
return;
|
|
}
|
|
this.counting = true;
|
|
this.endTime = Date.now() + this.remain;
|
|
this.tick();
|
|
},
|
|
// 暂停
|
|
pause() {
|
|
this.counting = false;
|
|
clearTimeout(this.tid);
|
|
},
|
|
// 重置
|
|
reset() {
|
|
this.pause();
|
|
this.remain = this.data.time;
|
|
this.setRemain(this.remain);
|
|
if (this.data.autoStart) {
|
|
this.start();
|
|
}
|
|
},
|
|
tick() {
|
|
if (this.data.millisecond) {
|
|
this.microTick();
|
|
}
|
|
else {
|
|
this.macroTick();
|
|
}
|
|
},
|
|
microTick() {
|
|
this.tid = simpleTick(() => {
|
|
this.setRemain(this.getRemain());
|
|
if (this.remain !== 0) {
|
|
this.microTick();
|
|
}
|
|
});
|
|
},
|
|
macroTick() {
|
|
this.tid = simpleTick(() => {
|
|
const remain = this.getRemain();
|
|
if (!isSameSecond(remain, this.remain) || remain === 0) {
|
|
this.setRemain(remain);
|
|
}
|
|
if (this.remain !== 0) {
|
|
this.macroTick();
|
|
}
|
|
});
|
|
},
|
|
getRemain() {
|
|
return Math.max(this.endTime - Date.now(), 0);
|
|
},
|
|
setRemain(remain) {
|
|
this.remain = remain;
|
|
const timeData = parseTimeData(remain);
|
|
if (this.data.useSlot) {
|
|
this.$emit('change', timeData);
|
|
}
|
|
this.setData({
|
|
formattedTime: parseFormat(this.data.format, timeData)
|
|
});
|
|
if (remain === 0) {
|
|
this.pause();
|
|
this.$emit('finish');
|
|
}
|
|
}
|
|
}
|
|
});
|