数据表格实现动态列

126 阅读2分钟

1、页面显示

在某些业务场景中,数据表会根据筛选不同的时间段,显示不同数量的列,默认列如图有6列

当选择时间为2023-10-11 - 2023-11-10为期一个月时,数据表则新增30列的数据,

同理,选择时间为9月11日至11月10日时,则新增60列数据

2、关键代码实现如下

  1. 获取到查询结果返回的数据datalist,并且取得detailResList作为动态列(时间维度)的基础数据

  2. 遍历detailResList取出对应的数据【statisticsDate,qty】push到dynamicColumns

  3. 将dynamicColumns拼接到默认列columns

    import dayjs from 'dayjs' import React, { useState, useRef, useMemo, useCallback } from 'react'

    import type { TableRef, TableProps, UseTableFormType } from '@proxyImport' import { useRequest, useMount, Table, DateRangePicker, Space, Button } from '@proxyImport'

    import { salesDetailPageApi, salesDetailExportApi } from '@/apis/oms/logisticsSystem/replenishmentSystem' import { defaultDateHandler } from '@/utils'

    const SalesDetails: React.FC = () => { const itableRef: TableRef = useRef(null) const [stores, setStores] = useState<Record<string, any>[]>([]) const [datalist, setDatalist] = useState({ list: [] as any }) const { request: getStoreRequest } = useRequest() const columns: TableProps['columns'] = useMemo(() => { // 动态列数据组合 const dynamicColumns: ITableProps['columns'] = [] // datalist表示查询接口返回的数据 const newList = datalist.list if (newList?.length > 0) { const detailResList = newList[0].detailResList ?? [] detailResList.length && detailResList.forEach((childItem: any, index: number) => { dynamicColumns.push({ title: ${childItem.statisticsDate}, dataIndex: ${childItem.qty}, width: 120, render: (value: any, record: Record<string, any>) => { return <>{record?.detailResList[index]?.qty}</> }, }) }) } return [ // 默认列 { title: '物料编码', dataIndex: 'materialCode', fixed: 'left', width: 150, }, { title: '物料名称', dataIndex: 'materialName', fixed: 'left', width: 150, }, { title: '店铺', dataIndex: 'storeName', fixed: 'left', width: 120, }, { title: '总销量', dataIndex: 'totalQty', fixed: 'left', width: 100, }, { title: '日均销量', dataIndex: 'dailyQty', fixed: 'left', width: 80, }, // 根据查询结果追加动态列 ...dynamicColumns, ] }, [datalist]) // 此处必须依赖外层的数据,否则查询后数据不能重新渲染

    const handleGetStores = useCallback(() => { getStoreRequest({ api: '/prediction/store/list', }).then((res) => setStores(res?.data ?? [])) }, [getStoreRequest]) useMount(() => { handleGetStores() }) const useTableForm = useMemo(() => { return { showReset: true, formItemOptions: [ { name: 'storeCode', itemName: 'select', formItemProps: { label: '关联店铺' }, itemProps: { style: { width: '200px' }, placeholder: '请选择管理店铺', fieldNames: { label: 'name', value: 'code' }, options: stores, showSearch: true, optionFilterProp: 'name', allowClear: false, }, }, { name: 'materialCode', itemName: 'input', formItemProps: { label: '物料编码' }, itemProps: { placeholder: '请输入物料编码', }, }, { name: 'materialName', itemName: 'input', formItemProps: { label: '物料名称' }, itemProps: { placeholder: '请输入物料名称', }, }, { name: 'createDate', itemName: 'input', formItemProps: { label: '日期' }, itemNode: , }, ], } }, [stores, handleGetStores]) const optItems = useMemo(() => { return ( ) }, []) const tableInitParams = useMemo(() => { return { storeCode: '200000', createDate: defaultDateHandler(30) } }, []) return (

    ) }

    export default SalesDetails