UNPKG

@cqmcui/cqmcui

Version:

轻量级移动端 Vue2、Vue3 组件库(支持小程序开发)

169 lines (168 loc) 5.44 kB
import { ref, reactive, computed, onMounted, onUnmounted, onActivated, onDeactivated, watch, toRefs, nextTick, resolveComponent, openBlock, createElementBlock, normalizeClass, createElementVNode, renderSlot, createVNode, toDisplayString, createCommentVNode } from "vue"; import { c as createComponent, l as getScrollTopRoot } from "./component-81a4c1d0.js"; import { u as useScrollParent } from "./index-43c34ac6.js"; import { r as requestAniFrame } from "./raf-729dad54.js"; import { Loading } from "@cqmcui/icons-vue"; import { _ as _export_sfc } from "./_plugin-vue_export-helper-cc2b3d55.js"; import "../locale/lang"; const { componentName, create, translate } = createComponent("infinite-loading"); const _sfc_main = create({ props: { modelValue: { type: Boolean, default: false }, hasMore: { type: Boolean, default: true }, threshold: { type: Number, default: 200 }, loadTxt: { type: String, default: "" }, loadMoreTxt: { type: String, default: "" }, useCapture: { type: Boolean, default: false } }, emits: ["scroll-change", "load-more", "update:modelValue"], components: { Loading }, setup(props, { emit, slots }) { const scroller = ref(); const scrollParent = useScrollParent(scroller); const state = reactive({ beforeScrollTop: 0, isInfiniting: false, y: 0, x: 0, distance: 0 }); const classes = computed(() => { const prefixCls = componentName; return { [prefixCls]: true }; }); const calculateTopPosition = (el) => { return !el ? 0 : el.offsetTop + calculateTopPosition(el.offsetParent); }; const isScrollAtBottom = () => { let offsetDistance = 0; let resScrollTop = 0; let direction = "down"; if (scrollParent.value == window) { const windowScrollTop = getScrollTopRoot(); if (scroller.value) { offsetDistance = calculateTopPosition(scroller.value) + scroller.value.offsetHeight - windowScrollTop - window.innerHeight; } resScrollTop = windowScrollTop; } else { const { scrollHeight, clientHeight, scrollTop } = scrollParent.value; offsetDistance = scrollHeight - clientHeight - scrollTop; resScrollTop = scrollTop; } if (state.beforeScrollTop > resScrollTop) { direction = "up"; } else { direction = "down"; } state.beforeScrollTop = resScrollTop; emit("scroll-change", resScrollTop); return offsetDistance <= props.threshold && direction == "down"; }; const handleScroll = () => { requestAniFrame(() => { if (!isScrollAtBottom() || !props.hasMore || state.isInfiniting) { return false; } else { state.isInfiniting = true; emit("update:modelValue", true); nextTick(() => emit("load-more")); } }); }; const scrollListener = () => { scrollParent.value && scrollParent.value.addEventListener("scroll", handleScroll, props.useCapture); }; const removeScrollListener = () => { scrollParent.value && scrollParent.value.removeEventListener("scroll", handleScroll, props.useCapture); }; onMounted(() => { scrollListener(); }); onUnmounted(() => { removeScrollListener(); }); const isKeepAlive = ref(false); onActivated(() => { if (isKeepAlive.value) { isKeepAlive.value = false; scrollListener(); } }); onDeactivated(() => { isKeepAlive.value = true; removeScrollListener(); }); watch( () => props.modelValue, (val) => { if (!val) { state.isInfiniting = false; } } ); return { classes, scroller, ...toRefs(state), translate, slots }; } }); const _hoisted_1 = { class: "cqmc-infinite__container" }; const _hoisted_2 = { class: "cqmc-infinite__bottom" }; const _hoisted_3 = { key: 0, class: "cqmc-infinite__bottom-box" }; const _hoisted_4 = { class: "cqmc-infinite__bottom-box__text" }; const _hoisted_5 = { class: "cqmc-infinite__bottom-tips" }; function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) { const _component_Loading = resolveComponent("Loading"); return openBlock(), createElementBlock("view", { class: normalizeClass(_ctx.classes), ref: "scroller" }, [ createElementVNode("view", _hoisted_1, [ renderSlot(_ctx.$slots, "default") ]), createElementVNode("view", _hoisted_2, [ _ctx.isInfiniting ? (openBlock(), createElementBlock("view", _hoisted_3, [ renderSlot(_ctx.$slots, "loading", {}, () => [ renderSlot(_ctx.$slots, "loading-icon", {}, () => [ createVNode(_component_Loading, { class: "cqmc-icon-loading cqmc-infinite__bottom-box__img" }) ]), createElementVNode("view", _hoisted_4, toDisplayString(_ctx.loadTxt || _ctx.translate("loading")), 1) ]) ])) : !_ctx.hasMore ? renderSlot(_ctx.$slots, "finished", { key: 1 }, () => [ createElementVNode("view", _hoisted_5, toDisplayString(_ctx.loadMoreTxt || _ctx.translate("loadMoreTxt")), 1) ]) : createCommentVNode("", true) ]) ], 2); } const index = /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render]]); export { index as default };