@zhsz/cool-design-dv
Version:
140 lines (139 loc) • 4.04 kB
JavaScript
import { defineComponent, useAttrs, ref, computed, watch, onMounted, onBeforeUnmount, openBlock, createElementBlock, createElementVNode, mergeProps, unref, toDisplayString } from "vue";
import dayjs from "dayjs";
import "./style.css";
const _hoisted_1 = { class: "my-dv-timer" };
const __default__ = defineComponent({
name: "DvTimer"
});
const _sfc_main = /* @__PURE__ */ defineComponent({
...__default__,
props: {
// 设定值,String为时间格式,Number是秒数, countdown为true, 是开始值, countdown为false时结束值
target: [String, Number],
// 显示格式
format: {
type: String,
default: "HH:mm:ss"
},
// 倒数模式
countdown: Boolean,
// 颜色
type: {
type: String,
validator(val) {
return ["primary", "success", "warning", "danger", "info"].includes(val);
}
},
// 自动开始
auto: Boolean,
// 执行时间隔 单位 ms
interval: {
type: Number,
default: 1e3
}
},
emits: ["start", "stop", "reset", "finish", "tick"],
setup(__props, { emit: __emit }) {
const props = __props;
const $attrs = useAttrs();
const $emit = __emit;
const timerId = ref();
const dayInstance = ref();
const targetDayjs = ref();
const minDayjs = ref();
const isFinish = ref(false);
const classes = computed(() => {
return {
"my-timer": true,
[`is-${props.type}`]: !!props.type,
"is-finish": isFinish.value
};
});
const displayValue = computed(() => {
return dayInstance.value ? dayInstance.value.format(props.format) : "";
});
function init() {
reset();
props.auto && start();
}
function getTarget() {
if (!props.target) {
return getMax();
}
if (typeof props.target === "number") {
return getMin().second(props.target);
}
if (typeof props.target === "string") {
return dayjs(`${getMin().format("YYYY-MM-DD")} ${props.target}`);
}
}
function getMin() {
return dayjs().hour(0).minute(0).second(0).millisecond(0);
}
function getMax() {
return dayjs().hour(23).minute(59).second(59);
}
function start() {
if (!dayInstance.value)
return;
clearInterval(timerId.value);
timerId.value = setInterval(() => {
tick();
}, props.interval);
$emit("start", dayInstance.value);
}
function reset() {
isFinish.value = false;
clearInterval(timerId.value);
minDayjs.value = Object.freeze(getMin());
targetDayjs.value = Object.freeze(getTarget());
dayInstance.value = props.countdown ? Object.freeze(getTarget()) : Object.freeze(getMin());
$emit("reset", dayInstance.value);
}
function tick() {
if (!dayInstance.value)
return;
if (props.countdown) {
dayInstance.value = Object.freeze(
dayInstance.value.subtract(props.interval, "millisecond")
);
if (dayInstance.value.valueOf() === minDayjs.value.valueOf()) {
isFinish.value = true;
}
} else {
dayInstance.value = Object.freeze(
dayInstance.value.add(props.interval, "millisecond")
);
if (dayInstance.value.valueOf() === targetDayjs.value.valueOf()) {
isFinish.value = true;
}
}
if (isFinish.value) {
clearInterval(timerId.value);
$emit("finish", dayInstance.value);
} else {
$emit("tick", dayInstance.value);
}
}
watch(
() => props.target,
() => {
init();
}
);
onMounted(() => {
init();
});
onBeforeUnmount(() => {
clearInterval(timerId.value);
});
return (_ctx, _cache) => {
return openBlock(), createElementBlock("div", _hoisted_1, [
createElementVNode("div", mergeProps({ class: classes.value }, unref($attrs)), toDisplayString(displayValue.value), 17)
]);
};
}
});
export {
_sfc_main as default
};