UNPKG

@wfrog/vc

Version:

vue3 组件库 vc

173 lines (167 loc) 5.85 kB
import { defineComponent, useCssVars, useTemplateRef, ref, computed, onMounted, onBeforeUnmount, createBlock, openBlock, Transition, withCtx, withDirectives, createElementVNode, normalizeClass, renderSlot, createVNode, unref, vShow, Teleport, mergeProps } from 'vue'; import '../../chunk/E_WRn0OP.mjs'; import { CaretBottom } from '@element-plus/icons-vue'; import { E as ElIcon } from '../../chunk/m2vp1CCf.mjs'; import { _ as _export_sfc } from '../../chunk/pcqpp-6-.mjs'; const _sfc_main$1 = /* @__PURE__ */ defineComponent({ __name: "child", props: { target: {}, right: { default: 40 }, bottom: { default: 40 }, visibilityHeight: { default: 200 }, parent: { type: Boolean } }, emits: ["inited"], setup(__props, { emit: __emit }) { useCssVars((_ctx) => ({ "v10480682": `${-_ctx.right}px`, "v003052db": `${_ctx.bottom}px` })); const props = __props; const emits = __emit; const backbottomRef = useTemplateRef("backbottomRef"); const myTarget = ref(); const diffHeight = ref(0); const scrollHeight = ref(0); const clientHeight = ref(0); const hasVerticalScrollbar = computed(() => scrollHeight.value > clientHeight.value); const visible = computed(() => hasVerticalScrollbar.value && diffHeight.value > props.visibilityHeight); const teleportTarget = ref(); const needTeleport = ref(false); function updateHeightData() { scrollHeight.value = myTarget.value.scrollHeight; clientHeight.value = myTarget.value.clientHeight; const scrollTop = myTarget.value.scrollTop; diffHeight.value = scrollHeight.value - clientHeight.value - scrollTop; } function scrollToBottom() { myTarget.value?.scrollTo({ top: myTarget.value.scrollHeight, behavior: "smooth" }); } function getTarget() { let eleTarget; if (props.parent) { eleTarget = backbottomRef.value?.parentElement; let container = eleTarget; let elScrollTarget = null; do { if (container && container.classList.contains("el-scrollbar__wrap")) { needTeleport.value = true; elScrollTarget = container; } container = container?.parentElement; } while (!elScrollTarget && container); if (elScrollTarget) { eleTarget = elScrollTarget; } return eleTarget; } if (props.target) { needTeleport.value = true; if (typeof props.target === "string") { eleTarget = document.querySelector(props.target); } else { eleTarget = props.target; } return eleTarget; } return document.documentElement; } onMounted(() => { myTarget.value = getTarget(); if (needTeleport.value) { teleportTarget.value = myTarget.value; } if (myTarget.value === document.documentElement) { teleportTarget.value = document.body; document.addEventListener("scroll", updateHeightData); } else { myTarget.value.addEventListener("scroll", updateHeightData); } updateHeightData(); emits("inited", teleportTarget.value); }); onBeforeUnmount(() => { if (myTarget.value === document.documentElement) { window.document.removeEventListener("scroll", updateHeightData); } else { myTarget.value.removeEventListener("scroll", updateHeightData); } }); return (_ctx, _cache) => { const _component_ElIcon = ElIcon; return openBlock(), createBlock(Transition, { name: "el-fade-in" }, { default: withCtx(() => [ withDirectives(createElementVNode("div", { ref_key: "backbottomRef", ref: backbottomRef, class: normalizeClass(_ctx.$style.wrapper) }, [ createElementVNode("div", { class: normalizeClass(_ctx.$style.container) }, [ createElementVNode("div", { class: normalizeClass(_ctx.$style.body), onClick: scrollToBottom }, [ renderSlot(_ctx.$slots, "default", {}, () => [ createVNode(_component_ElIcon, { class: normalizeClass(_ctx.$style.icon) }, { default: withCtx(() => [ createVNode(unref(CaretBottom)) ]), _: 1 }, 8, ["class"]) ]) ], 2) ], 2) ], 2), [ [vShow, unref(visible)] ]) ]), _: 3 }); }; } }); /* unplugin-vue-components disabled */const wrapper = "_wrapper_12g77_1"; const container = "_container_12g77_11"; const body = "_body_12g77_15"; const icon = "_icon_12g77_34"; const style0 = { wrapper: wrapper, container: container, body: body, icon: icon }; const cssModules = { "$style": style0 }; const Child = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__cssModules", cssModules]]); const _sfc_main = /* @__PURE__ */ defineComponent({ __name: "backbottom", props: { target: {}, right: { default: 40 }, bottom: { default: 40 }, visibilityHeight: { default: 200 }, parent: { type: Boolean } }, setup(__props) { const props = __props; const teleportTarget = ref(); function handleInited(val) { teleportTarget.value = val; } return (_ctx, _cache) => { return unref(teleportTarget) ? (openBlock(), createBlock(Teleport, { key: 0, to: unref(teleportTarget) }, [ createVNode(Child, mergeProps(props, { onInited: handleInited }), null, 16) ], 8, ["to"])) : (openBlock(), createBlock(Child, mergeProps({ key: 1 }, props, { onInited: handleInited }), null, 16)); }; } }); export { _sfc_main as _ };