antd6的table排序功能

antd6的table排序功能

  • 技术栈:react 19 / ts / react-query
  • 效果:升序->降序->去掉排序->升序一直循环
  • 如果不需要接口,可跳到实现 父组件
  • 请求参数 :
    • sort_by :排序字段(created_at/updated_at)
    • order_by :排序方向(asc/desc,默认asc)

接口实现

js 复制代码
// src\api\test.ts
import type { SortField } from "@/types/device";
import { apiClient } from "./http"; // 只是axios请求
import { useQuery } from "@tanstack/react-query";

export interface Response {
  list: []
  page: number
  size: number
  total: number
}

export interface Params {
  page?: number;
  pageSize?: number;
  sort_by?: SortField | '';
  order_by?: 'asc' | 'desc' | '';
}


export const useGetList = (params: Params) => {
  return useQuery<Response>({
    queryKey: ['useGetList', params],
    queryFn: async () => {
      const { data: response } = await apiClient.get('/test', { params: params })
      return response.data
    },
  })
}

定义类型

js 复制代码
// src\types\test.ts
// 可排序字段
export const SORTABLE_FIELDS = [
  'created_at',
  'updated_at',
] as const;

export type SortField = typeof SORTABLE_FIELDS[number];

export type SortOrderBE = 'asc' | 'desc' | undefined;
export type SortOrderUI = 'ascend' | 'descend';

父组件

tsx 复制代码
// src\views\test\index.tsx
import React, { useState } from 'react';
import { useGetList, type Device, type useGetDeviceListParams, } from '@/api/test';
import type { SortField } from '@/types/test';

import DeviceTable from './components/DeviceTable';

const INIT_VALUES = { page: 1, pageSize: 10 };

const DeviceManagement: React.FC = () => {

  const [params, setParams] = useState({ ...INIT_VALUES });
  
// ⭐这里是重点
  // 排序处理
  const handleSortChange = (sortBy?: SortField | '', orderBy?: 'asc' | 'desc' | '') => {
    setParams((prev) => ({
      ...prev,
      sort_by: sortBy ?? '',
      order_by: orderBy ?? '',
    }));
  };

  return (
    <>
      <DeviceTable
      // 多余的配置参数省略,也就是一些配置page/data之类
        sortBy={params.sort_by}
        orderBy={params.order_by}
        onSortChange={handleSortChange}
      />
    </>
  );
};
  
export default DeviceManagement;

子组件

js 复制代码
import React from 'react';
import { Table, type TableProps } from 'antd';
import type { Device } from '@/api/device';
import {  type SortField, type SortOrderBE, type SortOrderUI } from '@/types/test';

interface DeviceTableProps {
  sortBy?: SortField | '';
  orderBy?: SortOrderBE | ''; // 改为后端类型,允许空字符串
  onSortChange?: (sortBy: SortField | '', orderBy: SortOrderBE | '') => void;
}


// ⭐这里是重点
/* ---------- 工具 ---------- */
const toUIOrder = (be?: SortOrderBE | ''): SortOrderUI | undefined =>{
  return be === 'asc' ? 'ascend' : be === 'desc' ? 'descend' : undefined;
}
/**
 * 设备表格组件
 * 展示设备列表数据并提供分页和编辑功能
 */
const DeviceTable: React.FC<DeviceTableProps> = ({
  sortBy,
  orderBy,
  onSortChange,
}) => {

  // 表格列配置
  const columns = [
    {
      title: 'ID',
      dataIndex: 'id',
      key: 'id',
      width: 100,
    },
    {
      title: '创建时间',
      dataIndex: 'created_at',
      key: 'created_at',
      width: 170,
      sorter: true,
      sortOrder: sortBy === 'created_at' ? toUIOrder(orderBy) : null,
    },
    {
      title: '更新时间',
      dataIndex: 'updated_at',
      key: 'updated_at',
      width: 170,
      sorter: true,
      sortOrder: sortBy === 'updated_at' ? toUIOrder(orderBy) : null,
    },
  ];

// ⭐这里是重点
const handleTableChange: TableProps<Device>['onChange'] = (_, __, sorter) => {
  // 如果 sorter 是数组或者没有字段,直接返回
  const single = Array.isArray(sorter) ? sorter[0] : sorter;
  const field = single.field as SortField;
  // 三态:ascend → descend → null(取消)
  if (!single.order) {
    // 第三次点击:把 undefined 传出去
    onSortChange?.('', '');
    return;
  }
  const order = single.order === 'ascend' ? 'asc' : 'desc';
  onSortChange?.(field, order);
};

  return (
    <>
      <Table
        columns={columns}
        // 其他配置省略
        onChange={handleTableChange}
      />
    </>
  );
};

export default DeviceTable;
相关推荐
SoaringHeart2 小时前
Flutter最佳实践:路由弹窗终极版NSlidePopupRoute
前端·flutter
程序员小李白2 小时前
动画2详细解析
前端·css·css3
eason_fan2 小时前
Rspack核心解析:Rust重写Webpack的性能革命与本质
前端·前端工程化
诗意地回家2 小时前
淘宝小游戏反编译
开发语言·前端·javascript
徐同保2 小时前
react两个组件中间加一个可以拖动跳转左右大小的功能
前端·javascript·react.js
爱迪斯通3 小时前
MANUS:用于视觉、语言、行动模型创建的高保真第一人称数据采集设备
前端
bjzhang753 小时前
使用 HTML + JavaScript 实现在线知识挑战
前端·javascript·html
薛定谔的猫23 小时前
Cursor 系列(3):关于MCP
前端·cursor·mcp
sheji34163 小时前
【开题答辩全过程】以 基于web的拍卖系统设计与实现为例,包含答辩的问题和答案
前端