mirror of
https://github.com/youzan/vant.git
synced 2025-10-20 10:44:59 +00:00
[new feature] add CountDown component (#3805)
This commit is contained in:
127
src/count-down/index.js
Normal file
127
src/count-down/index.js
Normal file
@@ -0,0 +1,127 @@
|
||||
import { createNamespace } from '../utils';
|
||||
import { raf, cancelRaf } from '../utils/dom/raf';
|
||||
import { isSameSecond, parseTimeData, parseFormat } from './utils';
|
||||
|
||||
const [createComponent, bem] = createNamespace('count-down');
|
||||
|
||||
export default createComponent({
|
||||
props: {
|
||||
millisecond: Boolean,
|
||||
time: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
format: {
|
||||
type: String,
|
||||
default: 'HH:mm:ss'
|
||||
},
|
||||
autoStart: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
remain: 0
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
timeData() {
|
||||
return parseTimeData(this.remain);
|
||||
},
|
||||
|
||||
formattedTime() {
|
||||
return parseFormat(this.format, this.timeData);
|
||||
}
|
||||
},
|
||||
|
||||
watch: {
|
||||
time: {
|
||||
immediate: true,
|
||||
handler() {
|
||||
this.reset();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
start() {
|
||||
if (this.counting) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.counting = true;
|
||||
this.endTime = Date.now() + this.remain;
|
||||
this.tick();
|
||||
},
|
||||
|
||||
pause() {
|
||||
this.counting = false;
|
||||
cancelRaf(this.rafId);
|
||||
},
|
||||
|
||||
reset() {
|
||||
this.pause();
|
||||
this.remain = this.time;
|
||||
|
||||
if (this.autoStart) {
|
||||
this.start();
|
||||
}
|
||||
},
|
||||
|
||||
tick() {
|
||||
if (this.millisecond) {
|
||||
this.microTick();
|
||||
} else {
|
||||
this.macroTick();
|
||||
}
|
||||
},
|
||||
|
||||
microTick() {
|
||||
this.rafId = raf(() => {
|
||||
this.setRemain(this.getRemain());
|
||||
|
||||
if (this.remain !== 0) {
|
||||
this.microTick();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
macroTick() {
|
||||
this.rafId = raf(() => {
|
||||
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;
|
||||
|
||||
if (remain === 0) {
|
||||
this.pause();
|
||||
this.$emit('finish');
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
render(h) {
|
||||
return (
|
||||
<div class={bem()}>
|
||||
{this.slots('default', this.timeData) || this.formattedTime}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
Reference in New Issue
Block a user