SOURCE

import {ref, nextTick, onMounted, toValue, watch} from 'vue';
import BaseTable from '_components/comp/BaseTable.vue';
import {$axios} from '_api/axios';

// 参数处理
function getParams(ref, options) {
  const {val, getParamsCallback} = options;
  const paginationParams = ref.value?.isPagination === false ? {} : ref.value?.getPagination ?? {};
  const params = {
    ...paginationParams,
    ...val,
    ...(ref.value?.getSort ?? {}),
    ...(ref.value?.getFilter ?? {})
  };
  // 存在自定义Params回调处理
  if (getParamsCallback) {
    return getParamsCallback(params);
  }
  return params;
}

/**
 * 表格hook
 *
 * @params {object} options 配置对象
 * @property {promise} fetchData 自定义axios请求
 * @property {object} fetchOptions axios请求参数
 * @property {function} getParamsCallback 参数处理回调
 * @property {function} getResponseCallback 响应报文处理回调 @return { data, total }
 * @property {Array} defaultData 默认表格数据
 * @property {boolean} immediate 是否默认执行
 * @property {string} defaultRadio 默认单选
 * @property {string} defaultCheckbox 默认复选
 */
function useTableHook(
  options = {fetchData, fetchOptions, getParamsCallback, getResponseCallback, defaultData: [], immediate: false, defaultRadio, defaultCheckbox: []}
) {
  const {defaultData = [], immediate = false, fetchData, fetchOptions, getResponseCallback, defaultRadio, defaultCheckbox = []} = options;
  const tableData = ref([].concat(toValue(defaultData) || []));
  const currentPage = ref(1);
  const pageSize = ref(10);
  const total = ref(defaultData?.length || 0);
  const radio = ref(toValue(defaultRadio) || null);
  const checkbox = ref(toValue(defaultCheckbox) || null);
  const baseTablePaginationRef = ref(null);
  const tableLoading = ref(true);

  // 查询表格数据
  const queryTableData = (val = {}) => {
    nextTick(() => {
      queryData(val);
    });
  };

  const queryData = (val = {}) => {
    tableLoading.value = true;
    let request;
    const params = getParams(baseTablePaginationRef, {...options, val});
    // 存在自定义axios请求
    if (fetchData) {
      request = fetchData(params);
    } else {
      // 存在axios请求参数
      if (fetchOptions) {
        request = $axios({
          ...fetchOptions,
          data: {
            ...(fetchOptions?.data ?? {}),
            ...params
          }
        });
      }
    }
    try {
      request
        .then(res => {
          // 存在自定义Response数据回调处理
          const {data, total} = getResponseCallback ? getResponseCallback(res) : res;
          tableData.value = data;
          total.value = total || 0;
        })
        .catch(error => {
          total.value = 0;
          tableData.value = [];
        })
        .finally(() => {
          tableLoading.value = false;
        });
    } catch (error) {
      tableLoading.value = false;
      throw new Error('【fetchData、fetchOptions都未定义或类型错误】fetchData:函数, 返回类型为Promise; fetchOptions:一个符合axios规范的入参对象');
    }
  };

  watch(
    () => tableLoading.value,
    val => {
      if (baseTablePaginationRef.value) {
        baseTablePaginationRef.value.tableLoading = val;
      }
    },
    {immediate: true, deep: true}
  );

  // 是否默认执行
  if (immediate) {
    queryTableData();
  } else {
    onMounted(() => {
      tableLoading.value = false;
    });
  }
  return {
    BaseTablePagination: (props, context) => {
      return (
        <BaseTable
          {...context.attrs}
          ref={baseTablePaginationRef}
          total={total.value}
          data={tableData.value}
          v-model:currentPage={currentPage.value}
          v-model:pageSize={pageSize.value}
          v-model:radio={radio.value}
          v-model:checkbox={checkbox.value}
          v-slots={context.slots}
          onPaginationChange={v => {
            queryTableData();
          }}
          onSortChange={v => {
            baseTablePaginationRef.value.updatePagination();
            queryTableData();
          }}
          onFilterChange={v => {
            baseTablePaginationRef.value.updatePagination();
            queryTableData();
          }}
        ></BaseTable>
      );
    }, // 新的基础表格翻页组件
    queryTableData, // 查询表格数据
    updatePagination: val => baseTablePaginationRef.value.updatePagination(val), // 重置表格翻页对象
    updateCurrentPage: val => baseTablePaginationRef.value.updateCurrentPage(val), // 重置表格当前页码
    updatePageSize: val => baseTablePaginationRef.value.updatePageSize(val), // 重置表格当前单页个数
    updateRadio: val => baseTablePaginationRef.value.updateRadio(val), // 重置表格单选
    updateCheckbox: val => baseTablePaginationRef.value.updateCheckbox(val), // 重置表格复选
    baseTablePaginationRef, // 当前表格组件实例
    currentPage, // 当前页码
    pageSize, // 单页个数
    tableData, // 表格数据
    total, // 表格数据总数
    radio, // 表格单选
    checkbox, // 表格多选
    tableLoading
  };
}

export default useTableHook;
console 命令行工具 X clear

                    
>
console