Przeglądaj źródła

重新封装useTableData和usePagination

WanGxC 8 miesięcy temu
rodzic
commit
fc7189f0ed

+ 0 - 28
src/utils/useElTable.ts

@@ -1,28 +0,0 @@
-/**
- * 获取 El-Table的数据并处理total和loading
- * @param apiFunction 请求的接口函数
- * @param query 请求参数
- * @param tableData El-Table的数据
- * @param total El-Table数据的总条数
- * @param loading El-Table的loading状态
- */
-export async function useElTableData(apiFunction: Function, query: any, tableData: Ref<any[]>, total: Ref<number>, loading: Ref<boolean>) {
-  try {
-    loading.value = true;
-    const response = await apiFunction(query);
-    let responseData = response.data;
-    if (!Array.isArray(responseData)) {
-      responseData = [ responseData ];
-    }
-    total.value = response.total;
-    tableData.value = responseData;
-    return { success: true, data: responseData, code: response.code, msg: response.msg };
-  } catch (error) {
-    console.error('Error in useElTableData==> ', error);
-    return { success: false, error };
-  } finally {
-    loading.value = false;
-    await nextTick();
-    window.dispatchEvent(new Event('resize'));
-  }
-}

+ 22 - 15
src/utils/usePagination.ts

@@ -1,29 +1,36 @@
 /**
- * 分页改变获取数据
+ * 分页改变获取数据, 配合useTableData使用
  * @param getData 获取数据的方法, 在调用的文件处完成getData方法的实现后传入
  */
 export function usePagination(getData: Function) {
-  const tableData = ref([]);
-  const total = ref(0);
-  const currentPage = ref(1);
-  const pageSize = ref(10);
-
+  const tableOptions = ref({
+    data: [],
+    total: 0,
+    page: 1,
+    limit: 10,
+    loading: false
+  })
   /**
    * 分页改变
-   * @param newPage 当前页码
+   * @param newPageOrObj
    * @param newSize 每页条数
    */
-  async function handlePageChange(newPage: number, newSize: number) {
-    currentPage.value = newPage;
-    pageSize.value = newSize;
+  async function handlePageChange(newPageOrObj: any, newSize?: any) {
+    if (typeof newPageOrObj === 'object' && newPageOrObj.currentPage && newPageOrObj.pageSize) {
+      // 处理 vxe-pager 的分页参数
+      tableOptions.value.page = newPageOrObj.currentPage;
+      tableOptions.value.limit = newPageOrObj.pageSize;
+    } else {
+      // 处理 element-plus 的分页参数
+      tableOptions.value.page = newPageOrObj;
+      tableOptions.value.limit = newSize;
+    }
+
     await getData();
   }
 
   return {
-    tableData,
-    total,
-    currentPage,
-    pageSize,
+    tableOptions,
     handlePageChange
   };
-}
+}

+ 90 - 0
src/utils/useTableData.ts

@@ -0,0 +1,90 @@
+import { ElMessage } from 'element-plus';
+
+
+type ReactiveOrRef<T> = T | Ref<T>;
+
+interface PagerConfig {
+  total: number;
+  page: number;
+  limit: number;
+}
+
+interface DataStructure {
+  data?: any[];
+  pagerConfig?: PagerConfig;
+  loading?: boolean;
+}
+
+export async function useTableData(
+    apiFunction: Function,
+    query: any,
+    options: ReactiveOrRef<DataStructure | any>
+) {
+  const getReactiveValue = <T>(obj: ReactiveOrRef<T>, key: keyof T): T[keyof T] => {
+    if (isRef(obj)) {
+      return obj.value[key];
+    }
+    return obj[key];
+  };
+
+  const setReactiveValue = <T>(obj: ReactiveOrRef<T>, key: keyof T, value: any) => {
+    if (isRef(obj)) {
+      obj.value[key] = value;
+    } else {
+      obj[key] = value;
+    }
+  };
+
+  const getPagerConfig = (): any => {
+    if (getReactiveValue(options, 'pagerConfig')) {
+      return getReactiveValue(options, 'pagerConfig');
+    } else {
+      return {
+        total: getReactiveValue(options, 'total') || 0,
+        page: getReactiveValue(options, 'page') || 1,
+        limit: getReactiveValue(options, 'limit') || 10
+      };
+    }
+  };
+
+  const setTotal = (total: number) => {
+    if (getReactiveValue(options, 'pagerConfig')) {
+      const pagerConfig = getPagerConfig();
+      setReactiveValue(options, 'pagerConfig', { ...pagerConfig, total });
+    } else {
+      setReactiveValue(options, 'total', total);
+    }
+  };
+
+  const setLoading = (value: boolean) => {
+    if (getReactiveValue(options, 'loading') !== undefined) {
+      setReactiveValue(options, 'loading', value);
+    }
+  };
+
+  // 更新查询参数
+  const pagerConfig = getPagerConfig();
+  query = {
+    ...query,
+    page: pagerConfig.page,
+    limit: pagerConfig.limit
+  };
+
+  try {
+    setLoading(true);
+    const response = await apiFunction(query);
+
+    let responseData = Array.isArray(response.data) ? response.data : [ response.data ];
+    setReactiveValue(options, 'data', responseData);
+    setTotal(response.total);
+
+    return { success: true, data: responseData, code: response.code, msg: response.msg };
+  } catch (error) {
+    ElMessage.error('Table Error');
+    return { success: false, error };
+  } finally {
+    setLoading(false);
+    await nextTick();
+    window.dispatchEvent(new Event('resize'));
+  }
+}

+ 9 - 9
src/views/shop-information/components/PlatformDetail.vue

@@ -10,6 +10,8 @@ import * as api from '../api';
 import { Link, Picture as IconPicture } from '@element-plus/icons-vue';
 import { platformColumns } from '../useColumns';
 import router from '/@/router';
+import { useTableData } from '/@/utils/useTableData';
+import { usePagination } from '/@/utils/usePagination';
 
 
 const route = useRoute();
@@ -17,6 +19,7 @@ const platform = route.query.platform;
 const platformOverview: any = ref([]);
 const overviewLoading = ref();
 // const selectedTab = ref('1');
+const { tableOptions, handlePageChange } = usePagination(fetchPlatformDetail);
 const platformTableData = ref([]);
 const gridOptions: any = reactive({
   border: false,
@@ -34,9 +37,9 @@ const gridOptions: any = reactive({
     resizable: true
   },
   pagerConfig: {
-    total: 0,
-    page: 1,
-    limit: 10
+    total: tableOptions.value.total,
+    page: tableOptions.value.page,
+    limit: tableOptions.value.limit
   },
   loading: false,
   loadingConfig: {
@@ -58,11 +61,7 @@ async function fetchPlatformDetail() {
     page: gridOptions.pagerConfig.page,
     limit: gridOptions.pagerConfig.limit
   };
-  const res = await useResponse(query, api.getTableData, gridOptions);
-  gridOptions.pagerConfig.total = res.total;
-  gridOptions.pagerConfig.page = res.page;
-  gridOptions.pagerConfig.limit = res.limit;
-  platformTableData.value = res.data;
+  await useTableData(api.getTableData, query, gridOptions)
 }
 
 function pageChange({ pageSize, currentPage }: any) {
@@ -71,6 +70,7 @@ function pageChange({ pageSize, currentPage }: any) {
   fetchPlatformDetail();
 }
 
+
 async function fetchPlatformDetailOverview() {
   const res = await useResponse({ platform }, api.getPlatformDetailOverview, overviewLoading);
   platformOverview.value = res.data;
@@ -143,7 +143,7 @@ function handleNavigate(item: any) {
               v-model:currentPage="gridOptions.pagerConfig.page"
               v-model:pageSize="gridOptions.pagerConfig.limit"
               :total="gridOptions.pagerConfig.total"
-              @page-change="pageChange"
+              @page-change="handlePageChange"
           >
           </vxe-pager>
         </template>

+ 33 - 4
src/views/test/index.vue

@@ -1,15 +1,44 @@
-<script setup lang="ts">
-/**
+<script lang="ts" setup>/**
  * @Name: index.vue
  * @Description: 测试文件
  * @Author: Cheney
  */
+import { usePagination } from '/@/utils/usePagination';
+import * as api from '/@/views/shop-information/api';
+import { useTableData } from '/@/utils/useTableData';
+import { ElMessage } from 'element-plus';
 
-const myDay = dayjs().format("YYYY-MM-DD");
-console.log("(index.vue: 13)=> myDay", myDay);
+
+const { tableOptions, handlePageChange } = usePagination(fetchData);
+
+async function fetchData() {
+  const { code, msg } = await useTableData(api.getTableData, {}, tableOptions);
+  if (code === 2000) ElMessage.success({ message: msg, plain: true });
+}
+
+onMounted(() => {
+  fetchData();
+});
 </script>
 
 <template>
+  <el-card v-loading="tableOptions.loading">
+    <el-table :data="tableOptions.data" style="width: 100%">
+      <el-table-column label="Date" prop="date" width="180"/>
+      <el-table-column label="Name" prop="name" width="180"/>
+      <el-table-column label="Address" prop="address"/>
+    </el-table>
+    <div class="mt-2">
+      <el-pagination
+          v-model:current-page="tableOptions.page"
+          v-model:page-size="tableOptions.limit"
+          :page-sizes="[10, 20, 30, 40]"
+          :total="tableOptions.total"
+          layout="sizes, prev, pager, next, total"
+          @change="handlePageChange"
+      />
+    </div>
+  </el-card>
 
 </template>