choo-taro-ui-vue3
Version:
Taro UI Rewritten in Vue 3.0
219 lines (205 loc) • 6.57 kB
JavaScript
import { defineComponent, toRefs, createCommentVNode, toDisplayString, createTextVNode, resolveComponent, withCtx, createVNode, openBlock, createBlock, ref, reactive, watch, onMounted, onUnmounted, mergeProps } from 'vue';
const AtCountdownItem = defineComponent({
name: "AtCountdownItem",
props: {
num: {
type: Number,
default: 0
},
separator: {
type: String,
default: ":"
}
},
setup(props) {
function formatNum(num) {
return num <= 9 ? `0${num}` : `${num}`;
}
return {
...toRefs(props),
formatNum
};
}
});
// Binding optimization for webpack code-split
const _createCommentVNode$1 = createCommentVNode, _toDisplayString = toDisplayString, _createTextVNode = createTextVNode, _resolveComponent$1 = resolveComponent, _withCtx$1 = withCtx, _createVNode$1 = createVNode, _openBlock$1 = openBlock, _createBlock$1 = createBlock;
function _sfc_render$1(_ctx, _cache, $props, $setup, $data, $options) {
const _component_taro_text = process.env.TARO_ENV === "h5" ? _resolveComponent$1("taro-text") : "text";
const _component_taro_view = process.env.TARO_ENV === "h5" ? _resolveComponent$1("taro-view") : "view";
return (_openBlock$1(), _createBlock$1(_component_taro_view, { class: "at-countdown__item" }, {
default: _withCtx$1(() => [
_createCommentVNode$1(" countdown time-box "),
_createVNode$1(_component_taro_view, { class: "at-countdown__time-box" }, {
default: _withCtx$1(() => [
_createVNode$1(_component_taro_text, { class: "at-countdown__time" }, {
default: _withCtx$1(() => [
_createTextVNode(_toDisplayString(_ctx.formatNum(_ctx.num)), 1 /* TEXT */)
]),
_: 1 /* STABLE */
})
]),
_: 1 /* STABLE */
}),
_createCommentVNode$1(" separator "),
_createVNode$1(_component_taro_text, { class: "at-countdown__separator" }, {
default: _withCtx$1(() => [
_createTextVNode(_toDisplayString(_ctx.separator), 1 /* TEXT */)
]),
_: 1 /* STABLE */
})
]),
_: 1 /* STABLE */
}))
}
AtCountdownItem.render = _sfc_render$1;
const toSeconds = (day, hours, minutes, seconds) => day * 60 * 60 * 24 + hours * 60 * 60 + minutes * 60 + seconds;
const AtCountdown = defineComponent({
name: "AtCountdown",
components: {
AtCountdownItem
},
emits: ["time-up"],
props: {
isCard: Boolean,
isShowDay: Boolean,
isShowHour: { type: Boolean, default: true },
format: {
type: Object,
default: () => ({
day: "\u5929",
hours: "\u65F6",
minutes: "\u5206",
seconds: "\u79D2"
})
},
day: {
type: Number,
default: 0
},
hours: {
type: Number,
default: 0
},
minutes: {
type: Number,
default: 0
},
seconds: {
type: Number,
default: 0
}
},
onShow() {
this.setTimer();
},
onHide() {
this.clearTimer();
},
setup(props, { emit }) {
const { format, isCard, isShowDay, isShowHour } = toRefs(props);
const timer = ref(null);
const secondsRef = ref(toSeconds(props.day, props.hours, props.minutes, props.seconds));
const state = reactive(calculateTime());
watch(() => [
props.day,
props.hours,
props.minutes,
props.seconds
], ([
day,
hours,
minutes,
seconds
]) => {
secondsRef.value = toSeconds(day, hours, minutes, seconds);
clearTimer();
setTimer();
});
function setTimer() {
if (!timer.value)
countdown();
}
function clearTimer() {
if (timer.value) {
clearTimeout(timer.value);
}
}
function calculateTime() {
let [day_, hours_, minutes_, seconds_] = [0, 0, 0, 0];
if (secondsRef.value > 0) {
day_ = props.isShowDay ? Math.floor(secondsRef.value / (60 * 60 * 24)) : 0;
hours_ = Math.floor(secondsRef.value / (60 * 60)) - day_ * 24;
minutes_ = Math.floor(secondsRef.value / 60) - day_ * 24 * 60 - hours_ * 60;
seconds_ = Math.floor(secondsRef.value) - day_ * 24 * 60 * 60 - hours_ * 60 * 60 - minutes_ * 60;
}
return {
day_,
hours_,
minutes_,
seconds_
};
}
function countdown() {
Object.assign(state, calculateTime());
secondsRef.value--;
if (secondsRef.value < 0) {
clearTimer();
emit("time-up");
return;
}
timer.value = setTimeout(() => {
countdown();
}, 1e3);
}
onMounted(() => {
setTimer();
});
onUnmounted(() => {
clearTimer();
});
return {
...toRefs(state),
format,
isCard,
isShowDay,
isShowHour
};
}
});
// Binding optimization for webpack code-split
const _resolveComponent = resolveComponent, _openBlock = openBlock, _createBlock = createBlock, _createCommentVNode = createCommentVNode, _createVNode = createVNode, _mergeProps = mergeProps, _withCtx = withCtx;
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
const _component_at_countdown_item = _resolveComponent("at-countdown-item");
const _component_taro_view = process.env.TARO_ENV === "h5" ? _resolveComponent("taro-view") : "view";
return (_openBlock(), _createBlock(_component_taro_view, _mergeProps(_ctx.$attrs, {
class: ['at-countdown', {'at-countdown--card': _ctx.isCard }]
}), {
default: _withCtx(() => [
(_ctx.isShowDay)
? (_openBlock(), _createBlock(_component_at_countdown_item, {
key: 0,
num: _ctx.day_,
separator: _ctx.format?.day
}, null, 8 /* PROPS */, ["num", "separator"]))
: _createCommentVNode("v-if", true),
(_ctx.isShowHour)
? (_openBlock(), _createBlock(_component_at_countdown_item, {
key: 1,
num: _ctx.hours_,
separator: _ctx.format?.hours
}, null, 8 /* PROPS */, ["num", "separator"]))
: _createCommentVNode("v-if", true),
_createVNode(_component_at_countdown_item, {
num: _ctx.minutes_,
separator: _ctx.format?.minutes
}, null, 8 /* PROPS */, ["num", "separator"]),
_createVNode(_component_at_countdown_item, {
num: _ctx.seconds_,
separator: _ctx.format?.seconds
}, null, 8 /* PROPS */, ["num", "separator"])
]),
_: 1 /* STABLE */
}, 16 /* FULL_PROPS */, ["class"]))
}
AtCountdown.render = _sfc_render;
export default AtCountdown;