zy-vue-library/hooks/useListData/index.js

178 lines
7.2 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import { nextTick, ref } from "vue";
import { getDataType } from "../../utils/index.js";
import {
getQueryCriteria,
setQueryCriteria,
} from "../useQueryCriteria/index.js";
const verificationParameter = (api, options) => {
if (getDataType(api) !== "Function") throw new Error("api必须是一个函数");
if (getDataType(options) !== "Object")
throw new Error("options必须是一个对象");
if (options.immediate && getDataType(options.immediate) !== "Boolean")
throw new Error("options.immediate必须是一个布尔值");
if (options.usePagination && getDataType(options.usePagination) !== "Boolean")
throw new Error("options.usePagination必须是一个布尔值");
if (options.key && getDataType(options.key) !== "String")
throw new Error("options.key必须是一个字符串");
if (
options.callback &&
getDataType(options.callback) !== "Function" &&
getDataType(options.callback) !== "AsyncFunction"
)
throw new Error("options.callback必须是一个函数");
if (
options.before &&
getDataType(options.before) !== "Function" &&
getDataType(options.before) !== "AsyncFunction"
)
throw new Error("options.before必须是一个函数");
if (
options.defaultSearchForm &&
getDataType(options.defaultSearchForm) !== "Object"
)
throw new Error("options.defaultSearchForm必须是一个对象");
if (
options.clearSelection &&
getDataType(options.clearSelection) !== "Boolean"
)
throw new Error("options.clearSelection必须是一个布尔值");
if (
options.params &&
getDataType(options.params) !== "Object" &&
getDataType(options.params) !== "Function"
)
throw new Error("options.params必须是一个对象或者一个函数");
if (
options.isStorageQueryCriteria &&
getDataType(options.isStorageQueryCriteria) !== "Boolean"
)
throw new Error("options.isStorageQueryCriteria必须是一个布尔值");
if (
options.tabsActiveName &&
getDataType(options.tabsActiveName) !== "String"
)
throw new Error("options.tabsActiveName必须是一个字符串");
};
const getOptionParams = (params) => {
if (params) {
if (getDataType(params) === "Object") return params;
const paramsValue = params();
if (getDataType(paramsValue) !== "Object")
throw new Error("options.params为函数时必须存在返回值并且必须是一个对象");
else return paramsValue;
}
};
const getBeforeParams = (before, params) => {
if (before) {
const paramsValue = before(JSON.parse(JSON.stringify(params)));
if (getDataType(paramsValue) !== "Object")
throw new Error("options.before必须存在返回值并且必须是一个对象");
else return paramsValue;
}
};
/**
* @param {Function} api - 接口请求函数,用于获取列表数据
* @param {Object} [options] - 配置项(可选)
* @param {Function} [options.callback] - 数据获取完成后的回调函数,第一个参数为列表数据,第二个参数为接口返回数据
* @param {Function} [options.before] - 请求前执行的钩子函数,接收当前查询参数作为参数,必须返回一个对象
* @param {Object|Function} [options.params] - 额外的请求参数,可以是对象或返回对象的函数
* @param {Object} [options.defaultSearchForm] - 搜索表单默认值
* @param {boolean} [options.immediate=true] - 是否立即执行接口请求
* @param {boolean} [options.usePagination=true] - 是否使用分页功能
* @param {string} [options.key="list"] - 响应数据中存放列表数据的字段名
* @param {boolean} [options.clearSelection=true] - 调用 resetPagination 时是否清空表格选择项
* @param {boolean} [options.isStorageQueryCriteria=true] - 是否缓存当前查询条件
* @param {string} [options.tabsActiveName] - 当存在 Tabs 组件时,当前激活的 tab 名称,用于区分查询缓存
* @return {Object} 返回对象包含以下属性list 表格数据pagination 分页数据searchForm 搜索表单数据tableRef 表格实例getData 获取数据函数resetPagination 重置分页函数
* @returns {Object} 返回对象包含以下属性:
* - [list] {Ref<Array>} 表格数据,使用 Vue 的 ref 包裹的数组
* - [pagination] {Ref<{currentPage:number,pageSize:number,total:number}>} 分页信息对象,包含 currentPage、pageSize、total 字段,使用 ref 包裹
* - [searchForm] {Ref<Object>} 搜索表单数据对象,使用 Vue 的 ref 包裹
* - [tableRef] {Ref<ElTable|null>} 表格实例ref可用于调用表格方法
* - [getData] {Function} 获取或刷新列表数据的异步函数
* - [resetPagination] {Function} 重置分页并刷新数据的异步函数
*/
export default function useListData(api, options = {}) {
verificationParameter(api, options);
const immediate = options.immediate ?? true;
const usePagination = options.usePagination ?? true;
const key = options.key ?? "list";
const defaultSearchForm = options.defaultSearchForm ?? {};
const clearSelection = options.clearSelection ?? true;
const isStorageQueryCriteria = options.isStorageQueryCriteria ?? true;
const defaultPagination = { currentPage: 1, pageSize: 20, total: 0 };
const list = ref([]);
const queryCriteria = getQueryCriteria(options.tabsActiveName);
const pagination = ref(queryCriteria.pagination || defaultPagination);
const searchForm = ref(JSON.parse(JSON.stringify(defaultSearchForm)));
const tableRef = ref(null);
const getData = async () => {
const resData = await api({
...(usePagination
? {
curPage: pagination.value.currentPage,
limit: pagination.value.pageSize,
}
: {}),
...searchForm.value,
...(queryCriteria.searchForm || {}),
...(getBeforeParams(
options.before,
queryCriteria.searchForm || searchForm.value
) || {}),
...(getOptionParams(options.params) || {}),
});
if (usePagination) {
if (resData.page[key]) list.value = resData.page[key];
else list.value = resData[key] || resData.varList;
} else list.value = resData[key] || resData.varList;
if (usePagination)
pagination.value.total =
resData.page.totalCount || resData.page.totalResult;
options.callback && options.callback(list.value, resData);
!usePagination &&
clearSelection &&
tableRef.value &&
tableRef.value.clearSelection();
if (isStorageQueryCriteria) {
setQueryCriteria(
{
searchForm: {
...searchForm.value,
...(queryCriteria.searchForm || {}),
},
pagination: pagination.value,
},
options.tabsActiveName
);
await nextTick();
searchForm.value = queryCriteria.searchForm || searchForm.value;
}
};
immediate && getData().then();
const resetPagination = async () => {
list.value = [];
pagination.value = defaultPagination;
await nextTick();
await getData();
clearSelection && tableRef.value && tableRef.value.clearSelection();
const cloneSearchForm = searchForm.value;
searchForm.value = {};
await nextTick();
searchForm.value = cloneSearchForm;
};
return {
list,
pagination,
searchForm,
tableRef,
getData: async () => await getData(),
resetPagination: async () => await resetPagination(),
};
}