You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
100 lines
2.6 KiB
100 lines
2.6 KiB
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'); |
|
} |
|
}, |
|
}, |
|
});
|
|
|