vue-hooks-plus
Version:
Vue hooks library
118 lines (117 loc) • 3.25 kB
JavaScript
const vue = require("vue");
const useBoolean = require("../useBoolean");
const useEventListener = require("../useEventListener");
const useRequest = require("../useRequest");
const domTarget = require("../utils/domTarget");
const rect = require("../utils/rect");
const _interopDefaultLegacy = (e) => e && typeof e === "object" && "default" in e ? e : { default: e };
const useBoolean__default = /* @__PURE__ */ _interopDefaultLegacy(useBoolean);
const useEventListener__default = /* @__PURE__ */ _interopDefaultLegacy(useEventListener);
const useRequest__default = /* @__PURE__ */ _interopDefaultLegacy(useRequest);
const useInfiniteScroll = (service, options = {}) => {
const {
target,
isNoMore,
threshold = 100,
reloadDeps = [],
manual,
onBefore,
onSuccess,
onError,
onFinally
} = options;
const finalData = vue.ref();
const [loadingMore, { set: setLoadingMore }] = useBoolean__default.default();
const setFinalData = (mutateData) => {
finalData.value = mutateData;
};
const noMore = vue.computed(() => {
if (!isNoMore)
return false;
return isNoMore(finalData.value);
});
const { loading, run, runAsync, cancel } = useRequest__default.default(
async (lastData) => {
const currentData = await service(lastData);
if (!lastData) {
finalData.value = currentData;
} else {
finalData.value = {
...currentData,
list: [...lastData.list, ...currentData.list]
};
}
return currentData;
},
{
manual,
onFinally: (_, d, e) => {
setLoadingMore(false);
onFinally == null ? void 0 : onFinally(d, e);
},
onBefore: () => onBefore == null ? void 0 : onBefore(),
onSuccess: (d) => {
setTimeout(() => {
scrollMethod();
});
onSuccess == null ? void 0 : onSuccess(d);
},
onError: (e) => onError == null ? void 0 : onError(e)
}
);
const loadMore = () => {
if (noMore.value)
return;
setLoadingMore(true);
run(finalData.value);
};
const loadMoreAsync = () => {
if (noMore.value)
return;
setLoadingMore(true);
return runAsync(finalData.value);
};
const reload = () => run();
const reloadAsync = () => runAsync();
const scrollMethod = () => {
const el = domTarget.getTargetElement(target);
if (!el) {
return;
}
const scrollTop = rect.getScrollTop(el);
const scrollHeight = rect.getScrollHeight(el);
const clientHeight = rect.getClientHeight(el);
if (scrollHeight - scrollTop <= clientHeight + threshold) {
loadMore();
}
};
useEventListener__default.default(
"scroll",
() => {
if (loading.value || loadingMore.value) {
return;
}
scrollMethod();
},
{ target }
);
vue.watch(reloadDeps, () => {
run();
});
const _loading = vue.computed(() => !loadingMore.value && loading.value);
return {
data: vue.shallowReadonly(finalData),
loading: vue.readonly(_loading),
loadingMore,
noMore,
loadMore,
loadMoreAsync,
reload,
reloadAsync,
mutate: setFinalData,
scrollMethod,
cancel
};
};
module.exports = useInfiniteScroll;
;