首页 > 其他分享 >基于antdv通用的表格

基于antdv通用的表格

时间:2023-02-04 12:11:46浏览次数:32  
标签:基于 return 表格 filterParamsList pagination && antdv const

基于本一版需求做的通用表格,涵盖了导出功能、分页、入参、api路径,以及表格筛选

由于eslint报warning:React Hook useEffect has a missing dependency: 'xxx'. Either include it or remove the dependency array
无法解决这个问题,但又觉得改造后不符合笔者心里所想,遂记录下这个思路,希望未来可以解决这个问题。

  1. 需要与后台约定好表格ajax的返回数据,
  2. 由于后台规定的导出功能的参数与请求表格参数相同,仅仅是exp的不同,因而也做了兼容,如果这一块不需要则可以拿掉
  3. 请求数据的逻辑:getTableResource的参数1myPagination对象是初始定义的pagination对象,因而在初加载时会基于pagination对象进行请求,然后再分页时,会将当前changepagation对象传入函数内,因而,page&current会发生变动,分页功能完成
  4. 由于表格可能有过滤功能,且如果有过滤功能的话,过滤参数也不允许为null,因而有了动态filter功能,动态filter的实现:首先由外部传入filterParamsList数组(filterParamsList长度大于0时认为有过滤功能),在本组件加载时先遍历filterParamsList并在myInParams中配置对应的key,并且赋值为空数组,随后,在每次筛选时保存当前的filterObj,在遍历完毕filterParamsList后,如果filterObj有值则遍历filterObj将内部值重新赋予给myInParams,三目运算没值则赋空数组,filterParamsList必须要与表格的筛选参数一一对应!
/*
 * @Author: 
 * @Date: 2023-02-02 15:11:52
 * @LastEditTime: 2023-02-03 15:04:25
 * @LastEditors: 
 * @Description: 封装的通用表格,包含导出功能、分页、入参、api路径,以及表格筛选
 */
import { useEffect, useState } from 'react'
import Axios, { API } from '@/axios'
import { downloadFile } from "@/tools"
import { ExportBtn ,MyTitle  } from "@/components/common"
import { Table, } from 'antd'
/**
 * @export
 * @param {*} { 
 *  inParams :{} 入参,此处不做校验,直接传入
 *  filterParamsList,[] filter数组,为空数组说明不做校验
 *  listenRelyList  string[]  依赖值,useeffect使用
 * ajaxRequest:string api路径  API.candidateTypeTableResource
 * isNeedPagination: boolean 是否需要分页,默认是
 * exportFileName : string 导出的文件名  总体需要外部传入 `${year}年考生类型分析.xlsx`(全名是为了防止出现非xlsx文件) 不传则无导出按钮
 * tableScroll:{x:number,y:number}  表格宽长
 * titleName:  string  标题名,不传则无标题模块
 * @return {*} 
*/
 
export default function MyTable({
  inParams,
  filterParamsList,
  listenRelyList,
  ajaxRequest,
  exportFileName,
  titleName,
  isNeedPagination = true,
  tableScroll = { x: 1000 },
}) {

  // 是否有过滤数组,不影响进程
  const hasFilterArr = Array.isArray(filterParamsList) && filterParamsList.length > 0
  // 表格本身的过滤入参
  let myFilter = {}
  // 定义入参,外部传入的筛选值
  let myInParams = {
    // 装配初始入参
    ...inParams,
  }
  // 将表格本身的过滤入参覆盖到总入参对象本身内(如果有)
  const addFilterInParams = () => {
    if (myFilter && Object.keys(myFilter).length > 0) {
      Object.keys(myFilter).forEach(k => myInParams[k] = myFilter && myFilter[k] ? myFilter[k] : [])
    }
  }
  const [tableResource, setTableResource] = useState({
    columns: [],
    dataSource: [],
    tableLoading: false
  })
  const [exportLoading, setExportLoading] = useState(false)
  // 表格分页 
  const [pagination, setPagination] = useState(isNeedPagination ? {
    // showQuickJumper: true,
    showSizeChanger: true,
    pageSize: 10,
    current: 1, // 当前页码
    total: 0, // 总条数
    showTotal: (totals) => `共${totals}条`,
  } : false)
  useEffect(() => {
    // 是否有依赖数据 
    if (!Array.isArray(listenRelyList) && listenRelyList.length > 0) return
    // 判断listerData内部项是否都合法
    if (!listenRelyList.every(v => v && v.length)) return
    // api路径是否合法,影响进程
    if (!Boolean(API[ajaxRequest])) {
      console.error(`请校验api是否正确定义!`)
      return
    }
    getTableResource()
  }, [...listenRelyList])
  // 获取本组件列表数据
  const getTableResource = (mypagination = isNeedPagination ? pagination : false, exp = 2) => {
    if (hasFilterArr) {
      //  如果是undefined,则说明没有筛选或者是第一次进入  遍历传入的filterParams
      filterParamsList.forEach(v => {
        myInParams[v] = []
      })
      // 首先先遍历filterParams赋初值,然后走addFilterInParams,myfilter可能没有值,无值略过,有值说明用户当前进行了筛选,
      // 随即走的遍历则将filterParams的值覆盖了一遍,这就是筛选的逻辑
      addFilterInParams()
    }
    exp === 2 ? setTableResource(pre => { return { ...pre, tableLoading: true } }) : setExportLoading(true)
    // 在这里合并分页数据
    if (isNeedPagination) {
      const { current, pageSize } = mypagination
      myInParams[`page`] = current
      myInParams[`limit`] = pageSize
    }
    const path = API[ajaxRequest]
    //公司自己封装的ajax请求框架,不影响
    Axios.Request({
      path,
      formData: {
        ...myInParams,
        export: exp
      }
    }).then(res => {
      console.log('通用表格组件 res', res)
      exp === 2 ? setTableResource(pre => { return { ...pre, tableLoading: false } }) : setExportLoading(false)
      if (!EolAxios.checkResponse({ res })) return
      if (exp === 2) {
        const { dataSource, columns, size: pageSize, page: current, count: total } = res
        setTableResource(pre => {
          return {
            ...pre,
            columns,
            dataSource
          }
        })
        // 是分页才可用
        isNeedPagination && setPagination(pre => {
          return {
            ...pre,
            pageSize,
            current,
            total
          }
        })
      } else {
//导出功能
        res.file_id && downloadFile(res.file_id, exportFileName)
      }
    })
  }
  return (
    <div>
      {
        titleName && <MyTitle name={titleName} />
      }
      {
        exportFileName &&
        <ExportBtn
          loading={exportLoading} handleClick={() => getTableResource(pagination, 1)}
          disabled={!tableResource.dataSource.length > 0}
        />
      }
      <Table columns={tableResource.columns}
        scroll={{
          ...tableScroll
        }}
        rowKey={(record) => record.id}
        pagination={isNeedPagination ? pagination : false}
        bordered
        size='small'
        loading={tableResource.tableLoading}
        dataSource={tableResource.dataSource}
        onChange={
          (pagination, filter) => {
            myFilter = filter
            getTableResource(pagination)
          }
        }
      />
    </div>
  )
}

   <MyTable
          inParams={{
            year,
            province,
            category,
            batch,
            special
          }}
          exportFileName={`文件全名.xlsx`}
          filterParamsList={['filterParams1', 'filterParams2']}
          listenRelyList={['relyName1','relyName1']}
          ajaxRequest={API_Path}
   />

标签:基于,return,表格,filterParamsList,pagination,&&,antdv,const
From: https://www.cnblogs.com/hjk1124/p/17091252.html

相关文章