UNPKG

@daysnap/vue-use

Version:
130 lines (129 loc) 4.4 kB
import { isArray, isBoolean, isFunction, isObject, isString } from '@daysnap/utils'; import { computed, onBeforeMount, reactive, ref } from 'vue'; export function usePaging(task, options = {}) { const { initialStatus, immediate, scrollSelector = '.hor-scroll' } = options; const pagingStatus = reactive(Object.assign({ pagingIndex: 0, pagingSize: 10, pagingTotal: -1, pagingError: '', pagingLoading: '', }, initialStatus)); // 滚动到顶部 const scrollTop = () => { if (scrollSelector) { // 重置 const els = document.querySelectorAll(scrollSelector); const el = els[els.length - 1]; if (el) { el.scrollTop = 0; } } }; // 列表数据 // https://github.com/vuejs/core/issues/2136 const pagingData = ref([]); // 重置 const pagingReset = () => { pagingStatus.pagingIndex = 0; pagingStatus.pagingTotal = -1; pagingStatus.pagingError = ''; pagingStatus.pagingLoading = false; pagingData.value = []; }; // 请求数据 const pagingTrigger = (pagingIndex, options) => { const opt = { loading: false, toast: false }; if (isBoolean(options)) { opt.loading = options; opt.toast = options; } else if (isObject(options)) { Object.assign(opt, options); } // first page return top if (pagingIndex === 1) { // 需要异步 scrollTop 保证 tab 模式下不出问题 setTimeout(scrollTop); } // loading pagingStatus.pagingLoading = true; pagingStatus.pagingError = ''; // fetch data const promise = task([pagingIndex, pagingStatus.pagingSize], opt).then((res) => { let pagingList = []; let pagingTotal = -1; if (isArray(res)) { ; [pagingList, pagingTotal] = res; } else { ; ({ pagingList, pagingTotal } = res); } // 有的接口当没有数据的时候,数据字段都没有了,所以这里兼容一下 if (!pagingList) { pagingList = []; } pagingStatus.pagingIndex = pagingIndex; pagingStatus.pagingTotal = pagingTotal; pagingData.value = pagingIndex === 1 ? pagingList : [...pagingData.value, ...pagingList]; // 为了兼容 接口 不返回 总数的情况下,如果 pagingList 给的是空数组,则认为没有更多数据了 if (!pagingList.length) { pagingStatus.pagingTotal = pagingData.value.length; } }); (promise.toast ? promise.toast((_, msg) => { pagingStatus.pagingError = msg; return opt.toast; }) : promise.catch((err) => { pagingStatus.pagingError = isString(err) ? err : JSON.stringify(err); })).finally(() => { pagingStatus.pagingLoading = false; if (isFunction(options)) { options(pagingStatus.pagingError); } // first page error if (pagingStatus.pagingError && pagingIndex === 1) { pagingStatus.pagingIndex = pagingIndex; pagingStatus.pagingTotal = -1; pagingData.value = []; } }); }; // 刷新 const pagingRefresh = (options) => { pagingTrigger(1, options); }; // 加载 const pagingLoad = (options) => { if (pagingFinished.value) { if (isFunction(options)) { options(); } return console.log('没有更多了'); } pagingTrigger(pagingStatus.pagingIndex + 1, options); }; // 是否加载完毕 const pagingFinished = computed(() => { return pagingStatus.pagingTotal > 0 && pagingData.value.length >= pagingStatus.pagingTotal; }); // 初始加载 onBeforeMount(() => { if (immediate) { pagingRefresh(); } }); return { pagingFinished, pagingData, pagingStatus, pagingTrigger, pagingRefresh, pagingLoad, pagingReset, }; }