封装ProTable组件

今天分享一篇关于ProComponents (ant.design)的文章,后面也会围绕ProTable这个组件去更新一个比较好用的table。

这次主要用到的技术点:

import { createContext, useEffect } from 'react';

import { useRef, useState } from 'react';

import ProTable from '@ant-design/pro-table';

封装ProTable组件_第1张图片

import { createContext, useEffect } from 'react';

import { useRef, useState } from 'react';

import type { ActionType, ProColumnType } from '@ant-design/pro-table';

import ProTable from '@ant-design/pro-table';

import { Space, Table } from 'antd';

import type { AlertRenderType } from '@ant-design/pro-table/lib/components/Alert';

import { history } from 'umi';

import type { SizeType } from '@ant-design/pro-form/lib/BaseForm';

import type { SearchConfig } from '@ant-design/pro-table/lib/components/Form/FormRender';

//定义当前组件接受的参数以及定义的类型

type CustomTableProps = {

  title?: string | JSX.Element[];

  filter?: string | JSX.Element[];

  columns?: ProColumnType[];

  toolBarComponents?: JSX.Element[];

  tableAlertOptionRender?: AlertRenderType | undefined;

  hideOptions?: boolean;

  reload?: boolean;

  pagination?: boolean;

  tableActionRef?: React.MutableRefObject;

  dataRow?: T;//这个参数一般用不到,使用到特殊需求的,例如翻译字段,当请求数据只返回code,需要去翻译中文的时候  可以使用此字段来改变当前某一行数据的发生变化

  search?: false | SearchConfig;//table是否带搜索字段,官网默认的ProTable自带搜索,不需要可以设置为false

  queryPage?: (params: Partial) => Promise<{ success: boolean; total: number; data: T[] }>;

queryPage这个字段是用来传接口使用的  官网给的有一个api:{request}是用来请求数据的  我们可以把接口传递进去  让组件去完成,

  tableSearchParams?: any;

  defaultSort?: string[];

  defaultSize?: SizeType;

};

//这个方法可以当作回调去处理,比如我们在自定义搜索的时候可以使用其方法的去调用和刷新接口,自定义搜索我们下一章再贴出来

export const NpTableContext = createContext<{

  actionRef?: React.MutableRefObject;

  onSearhParamsChanged?: (params: any) => void;

}>({});

const CustomTable = (props: CustomTableProps) => {

  const {

    title,

    filter,

    columns,

    hideOptions,

    tableActionRef,

    toolBarComponents,

    tableAlertOptionRender,

    dataRow,

    sourceRow,

    queryPage,

    tableSearchParams,

    search,

    defaultSort,

    defaultSize,

    reload = true,

    pagination = false

  } = props;

  const currentPathName = history.location.pathname;

  const initColumnsState = localStorage.getItem(currentPathName) ? JSON.parse(localStorage.getItem(currentPathName)!.toString()) : undefined;

  const [dataSource, setDataSource] = useState([]);

  const [searchParams, setSearchParams] = useState>({});

  const [currentPage, setCurrentPage] = useState(1);

  useEffect(() => {

    if (dataRow) {

      setDataSource(dataSource.map(x => {

        if (x.id === dataRow.id) {

          return { ...dataRow }

        } else {

          return x;

        }

      }))

    }

    // eslint-disable-next-line react-hooks/exhaustive-deps

//dataRow  需要对某一条数据修改可以是用这个方法  更新dataSource

  }, [dataRow])

  useEffect(() => {

    if (sourceRow) {

      setDataSource(sourceRow)

    }

    // eslint-disable-next-line react-hooks/exhaustive-deps

//dataRow  需要对整个table数据修改可以是用这个方法  更新dataSource

  }, [sourceRow])

  const onSearhParamsChanged = (params: Partial) => {

//搜索

    const newParams = { ...searchParams, ...params };

    setSearchParams(newParams);

  }

  const actionRef = useRef();

//调用table的方法

  return (

   

      actionRef: tableActionRef || actionRef,

      onSearhParamsChanged: onSearhParamsChanged

    }}>

     

        style={{ padding: 0, margin: 0 }}

        rowKey='id'

        dataSource={dataSource}

        defaultSize={defaultSize}

        pagination={

          pagination ? {

            showSizeChanger: false,

            current: currentPage

          } :

            {

              showSizeChanger: true,

              onShowSizeChange: (current, size) => {

                setCurrentPage(current)

                localStorage.setItem(currentPathName + '/pageSize', size.toString());

              },

              pageSize: Number(localStorage.getItem(currentPathName + '/pageSize')) || 10,

              current: currentPage

            }

        }

        toolBarRender={

          (toolBarComponents) ? () => [toolBarComponents,] : false

        }

        search={(search) || false}

        toolbar={{

          title: (title) ? title : '',

          filter: (filter) ? filter : ''

        }}

//rowSelection 例如我们对table有复选框之类的操作可以加上这段

        rowSelection={tableAlertOptionRender ?

          { selections: [Table.SELECTION_ALL, Table.SELECTION_INVERT], } : false}

        tableAlertRender={({ selectedRowKeys, onCleanSelected }) => (

         

           

              已选 {selectedRowKeys.length} 项

             

                取消选择

             

           

         

        )}

        tableAlertOptionRender={tableAlertOptionRender}

//options=false的时候  是不显示操作栏

        options={

          hideOptions ? false :

            {

              density: true,

              fullScreen: true,

              reload: reload,

              search: false,

              setting: {

              },

            }

        }

        actionRef={tableActionRef || actionRef}

        columns={columns}

//columnsState  针对列的设置

        columnsState={{

          defaultValue: initColumnsState,

          persistenceType: 'localStorage',

          persistenceKey: currentPathName,

        }}

        params={tableSearchParams || searchParams}

        request={async (params: any, sorter) => {

          const sort = sorter

            ? JSON.stringify(sorter)

              .replaceAll('"', '')

              .replaceAll('{', '')

              .replaceAll('}', '')

              .replaceAll('end', '')

              .replaceAll(':', ',')

            : undefined;

          const reqParams = {

            ...params,

            page: params.current - 1,

            size: params.pageSize,

            sort: [sort, defaultSort || undefined],

          };

          const result = await queryPage?.(reqParams);

          setDataSource(result?.data || [])

          return {

            success: result?.success,

            data: result?.data,

            total: result?.total

          }

        }}

设置固定列

        scroll={{ x: 'max-content' }}

      />

   

  );

};

export default CustomTable;

使用方法:

方法一:

 const tableAttribute = {

    columns: tagInfoColumns,

    toolBarComponents: [],

    queryPage: (params: Partial) => generalTagInfoRequest.queryPage(params),

    defaultSort: ['modifiedAt,desc'],

  }

方法二:

这样传是因为某些特殊情况下 我们需要把拿到的数据处理后才能渲染,如果我们再组件内处理 会导致复用性比较差 所以再父组件内处理好 传入table组件 可以使组件复用性最大化   我们既可以传入储存的数据又可以使用ProTable中的操作栏

const tableAttribute = {

        columns: orderColumns,

        toolBarComponents: [],

        queryPage: async (params: Partial) => {

            const result = await getOrderRequest.queryPage({ ...params, orderType: 'ADJ' })

            if (result.success) {

                handleCompanyListData();

                getFiltered(result.data)

            }

            return {

                data: result.data,

                success: result.success,

                total: result.total,

            }

        },

        defaultSort: ['modifiedAt,desc'],

        sourceRow: dataRow,

    }

{...tableAttribute} />

需求不是很复杂的情况下  官网给的api足够使用  大多数方法都是根据官网给的例子去延申的,下一章贴出针对ProTable组件的 自定义搜索,很多方法还没有写出来  官网给的例子  这个组件基本都支持,在这里就不贴出来了   

你可能感兴趣的:(react.js,前端,前端框架)