@wfrog/vc
Version:
vue3 组件库 vc
173 lines (167 loc) • 5.85 kB
JavaScript
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 _ };