choo-taro-ui-vue3
Version:
Taro UI Rewritten in Vue 3.0
228 lines (220 loc) • 8.65 kB
JavaScript
import Taro from '@tarojs/taro';
import { defineComponent, ref, reactive, computed, onMounted, toRefs, createCommentVNode, resolveComponent, createVNode, withCtx, openBlock, createBlock, normalizeClass, renderSlot, normalizeStyle, toDisplayString, createTextVNode, mergeProps } from 'vue';
const AtNoticebar = defineComponent({
name: "AtNoticebar",
emits: ["close", "goto-more"],
props: {
close: Boolean,
single: Boolean,
marquee: Boolean,
showMore: Boolean,
speed: {
type: Number,
default: 100
},
moreText: {
type: String,
default: "\u67E5\u770B\u8BE6\u60C5"
},
icon: String
},
setup(props, { emit }) {
const timeout = ref(null);
const interval = ref(null);
const state = reactive({
dura: 15,
show: true,
close_: props.marquee ? false : props.close,
showMore_: !props.single ? false : props.showMore,
animationElId: `J_${Math.ceil(Math.random() * 1e6).toString(36)}`,
animationData: { actions: [{}] },
isWEB: Taro.getEnv() === Taro.ENV_TYPE.WEB
});
const rootClasses = computed(() => ({
"at-noticebar": true,
"at-noticebar--marquee": props.marquee,
"at-noticebar--weapp": props.marquee && !state.isWEB,
"at-noticebar--single": !props.marquee && props.single
}));
const animationStyle = computed(() => {
const style = {};
if (props.marquee) {
style.animationDuration = `${state.dura}s`;
}
return style;
});
const innerContentClasses = computed(() => ({
"at-noticebar__content-inner": true,
[`${state.animationElId}`]: props.marquee
}));
const iconClasses = computed(() => ({
"at-icon": true,
[`at-icon-${props.icon}`]: Boolean(props.icon)
}));
function handleClose(event) {
state.show = false;
emit("close", event);
}
function onGotoMore(event) {
emit("goto-more", event);
}
function initWebAnimation() {
const elem = document.querySelector(`.${state.animationElId}`);
if (!elem)
return;
const width = elem.getBoundingClientRect().width;
state.dura = width / +props.speed;
}
function initMiniAppAnimation() {
const query = Taro.createSelectorQuery();
query.select(`.${state.animationElId}`).boundingClientRect().exec((res) => {
const queryRes = res[0];
if (!queryRes)
return;
const { width } = queryRes;
const dura = width / +props.speed;
const animation = Taro.createAnimation({
duration: dura * 1e3
});
const resetAnimation = Taro.createAnimation({
duration: 0
});
const resetOpacityAnimation = Taro.createAnimation({
duration: 0
});
const animateBody = () => {
resetOpacityAnimation.opacity(0).step();
state.animationData = resetOpacityAnimation.export();
setTimeout(() => {
resetAnimation.translateX(0).step();
state.animationData = resetAnimation.export();
}, 300);
setTimeout(() => {
resetOpacityAnimation.opacity(1).step();
state.animationData = resetOpacityAnimation.export();
}, 600);
setTimeout(() => {
animation.translateX(-width).step();
state.animationData = animation.export();
}, 900);
};
animateBody();
interval.value = setInterval(animateBody, dura * 1e3 + 1e3);
});
}
function initAnimation() {
timeout.value = setTimeout(() => {
timeout.value = null;
if (state.isWEB)
initWebAnimation();
else
initMiniAppAnimation();
}, 100);
}
onMounted(() => {
if (!props.marquee)
return;
initAnimation();
});
return {
...toRefs(state),
...toRefs(props),
rootClasses,
iconClasses,
innerContentClasses,
animationStyle,
handleClose,
onGotoMore
};
}
});
// Binding optimization for webpack code-split
const _createCommentVNode = createCommentVNode, _resolveComponent = resolveComponent, _createVNode = createVNode, _withCtx = withCtx, _openBlock = openBlock, _createBlock = createBlock, _normalizeClass = normalizeClass, _renderSlot = renderSlot, _normalizeStyle = normalizeStyle, _toDisplayString = toDisplayString, _createTextVNode = createTextVNode, _mergeProps = mergeProps;
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
const _component_taro_text = process.env.TARO_ENV === "h5" ? _resolveComponent("taro-text") : "text";
const _component_taro_view = process.env.TARO_ENV === "h5" ? _resolveComponent("taro-view") : "view";
return (_ctx.show)
? (_openBlock(), _createBlock(_component_taro_view, _mergeProps({ key: 0 }, _ctx.$attrs, { class: _ctx.rootClasses }), {
default: _withCtx(() => [
_createCommentVNode(" close icon "),
(_ctx.close_)
? (_openBlock(), _createBlock(_component_taro_view, {
key: 0,
class: "at-noticebar__close",
onTap: _ctx.handleClose
}, {
default: _withCtx(() => [
_createVNode(_component_taro_text, { class: "at-icon at-icon-close" })
]),
_: 1 /* STABLE */
}, 8 /* PROPS */, ["onTap"]))
: _createCommentVNode("v-if", true),
_createCommentVNode(" content "),
_createVNode(_component_taro_view, { class: "at-noticebar__content" }, {
default: _withCtx(() => [
_createCommentVNode(" icon "),
(_ctx.icon)
? (_openBlock(), _createBlock(_component_taro_view, {
key: 0,
class: "at-noticebar__content-icon"
}, {
default: _withCtx(() => [
_createVNode(_component_taro_text, {
class: _normalizeClass(_ctx.iconClasses)
}, null, 8 /* PROPS */, ["class"])
]),
_: 1 /* STABLE */
}))
: _createCommentVNode("v-if", true),
_createCommentVNode(" text "),
_createVNode(_component_taro_view, { class: "at-noticebar__content-text" }, {
default: _withCtx(() => [
_createCommentVNode(" default content slot "),
_createVNode(_component_taro_view, {
id: _ctx.animationElId,
animation: _ctx.animationData,
class: _normalizeClass(_ctx.innerContentClasses),
style: _normalizeStyle(_ctx.animationStyle)
}, {
default: _withCtx(() => [
_renderSlot(_ctx.$slots, "default")
]),
_: 3 /* FORWARDED */
}, 8 /* PROPS */, ["id", "animation", "class", "style"]),
_createCommentVNode(" show more content "),
(_ctx.showMore_)
? (_openBlock(), _createBlock(_component_taro_view, {
key: 0,
class: "at-noticebar__more",
onTap: _ctx.onGotoMore
}, {
default: _withCtx(() => [
_createVNode(_component_taro_text, { class: "text" }, {
default: _withCtx(() => [
_createTextVNode(_toDisplayString(_ctx.moreText), 1 /* TEXT */)
]),
_: 1 /* STABLE */
}),
_createVNode(_component_taro_view, { class: "at-noticebar__more-icon" }, {
default: _withCtx(() => [
_createVNode(_component_taro_text, { class: "at-icon at-icon-chevron-right" })
]),
_: 1 /* STABLE */
})
]),
_: 1 /* STABLE */
}, 8 /* PROPS */, ["onTap"]))
: _createCommentVNode("v-if", true)
]),
_: 3 /* FORWARDED */
})
]),
_: 3 /* FORWARDED */
})
]),
_: 3 /* FORWARDED */
}, 16 /* FULL_PROPS */, ["class"]))
: _createCommentVNode("v-if", true)
}
AtNoticebar.render = _sfc_render;
export default AtNoticebar;