UNPKG

taro-ui-vue3

Version:

Taro UI Rewritten in Vue 3.0

211 lines (210 loc) 5.9 kB
import { h, defineComponent, reactive, onMounted, computed, ref, mergeProps } from "vue"; import Taro from "@tarojs/taro"; import {Text, View} from "@tarojs/components"; const AtNoticebar = defineComponent({ name: "AtNoticebar", props: { close: Boolean, single: Boolean, marquee: Boolean, showMore: Boolean, speed: { type: Number, default: 100 }, moreText: { type: String, default: "\u67E5\u770B\u8BE6\u60C5" }, icon: String, onClose: Function, onGotoMore: Function }, setup(props, {attrs, slots}) { const env = Taro.getEnv(); 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, animElemId: `J_${Math.ceil(Math.random() * 1e6).toString(36)}`, animationData: {actions: [{}]}, isWEB: env === 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["animation-duration"] = `${state.dura}s`; } return style; }); const innerContentClasses = computed(() => ({ "at-noticebar__content-inner": true, [`${state.animElemId}`]: props.marquee })); const iconClasses = computed(() => ({ "at-icon": true, [`at-icon-${props.icon}`]: Boolean(props.icon) })); function handleClose(event) { var _a; state.show = false; (_a = props.onClose) == null ? void 0 : _a.call(props, event); } function onGotoMore(event) { var _a; (_a = props.onGotoMore) == null ? void 0 : _a.call(props, event); } function initWebAnimation() { const elem = document.querySelector(`.${state.animElemId}`); if (!elem) return; const width = elem.getBoundingClientRect().width; state.dura = width / +props.speed; } function initMiniAppAnimation() { const query = Taro.createSelectorQuery(); query.select(`.${state.animElemId}`).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 animBody = () => { 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); }; animBody(); interval.value = setInterval(animBody, 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 () => { if (!state.show) return null; const closeIconVNode = h(View, { class: "at-noticebar__close", onTap: handleClose }, { default: () => [ h(Text, { class: "at-icon at-icon-close" }) ] }); const contentIconVnode = h(View, { class: "at-noticebar__content-icon" }, { default: () => [ h(Text, { class: iconClasses.value }) ] }); const showMoreContentVnode = h(View, { class: "at-noticebar__more", onTap: onGotoMore.bind(this) }, { default: () => [ h(Text, { class: "text" }, {default: () => props.moreText}), h(View, { class: "at-noticebar__more-icon" }, { default: () => [ h(Text, { class: "at-icon at-icon-chevron-right" }) ] }) ] }); const defaultSlotVnode = h(View, { id: state.animElemId, animation: state.animationData, class: innerContentClasses.value, style: animationStyle.value }, {default: () => { var _a; return (_a = slots.default) == null ? void 0 : _a.call(slots); }}); return h(View, mergeProps(attrs, { class: rootClasses.value }), { default: () => [ state._close && closeIconVNode, h(View, { class: "at-noticebar__content" }, { default: () => [ props.icon && contentIconVnode, h(View, { class: "at-noticebar__content-text" }, { default: () => [ defaultSlotVnode, state._showMore && showMoreContentVnode ] }) ] }) ] }); }; } }); var noticebar_default = AtNoticebar; export { noticebar_default as default };