@daysnap/vue-use
Version:
daysnap vue hooks
130 lines (129 loc) • 4.4 kB
JavaScript
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,
};
}