@cqmcui/cqmcui
Version:
轻量级移动端 Vue2、Vue3 组件库(支持小程序开发)
169 lines (168 loc) • 5.44 kB
JavaScript
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
};