如何在Ant-Design Table组件实现自定义排序?

Ant-Design中使用Table组件实现多列排序,怎么实现自定义排序(默认排序顺序是升序->降序->取消排序)。以及只能通过点击上下箭头进行排序,而不是点击列头进行排序。实现效果类似Element-UITable组件的列排序的交互。

通过提供对应的API,没能实现这样的功能。

阅读 280
1 个回答
import React, { useState } from 'react';
import { Table } from 'antd';
import { CaretUpOutlined, CaretDownOutlined } from '@ant-design/icons';

const CustomTable = () => {
  const [sortState, setSortState] = useState({
    column: null,
    order: null // null: 未排序, 'ascend': 升序, 'descend': 降序
  });

  // 自定义排序图标
  const CustomSorter = ({ column }) => {
    const isActive = sortState.column === column;
    return (
      <span className="custom-sorter">
        <CaretUpOutlined 
          className={`sort-caret ascending ${isActive && sortState.order === 'ascend' ? 'active' : ''}`}
          onClick={(e) => {
            e.stopPropagation();
            handleSort(column, 'ascend');
          }}
        />
        <CaretDownOutlined 
          className={`sort-caret descending ${isActive && sortState.order === 'descend' ? 'active' : ''}`}
          onClick={(e) => {
            e.stopPropagation();
            handleSort(column, 'descend');
          }}
        />
      </span>
    );
  };

  const handleSort = (column, order) => {
    if (sortState.column === column && sortState.order === order) {
      setSortState({
        column: null,
        order: null
      });
    } else {
      setSortState({
        column,
        order
      });
    }
  };

  const columns = [
    {
      title: '姓名',
      dataIndex: 'name',
      key: 'name',
      sortDirections: ['ascend', 'descend'],
      showSorterTooltip: false,
      sorter: true,
      title: (
        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
          <span>姓名</span>
          <CustomSorter column="name" />
        </div>
      ),
    },
    {
      title: '年龄',
      dataIndex: 'age',
      key: 'age',
      sortDirections: ['ascend', 'descend'],
      showSorterTooltip: false,
      sorter: true,
      title: (
        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
          <span>年龄</span>
          <CustomSorter column="age" />
        </div>
      ),
    },
    // ... 
  ];

  const data = [
    { key: '1', name: '张三', age: 25 },
    { key: '2', name: '李四', age: 30 },
    { key: '3', name: '王五', age: 28 },
  ];

  const handleTableChange = (pagination, filters, sorter) => {
    if (!sortState.column || !sortState.order) {
      return data;
    }

    return [...data].sort((a, b) => {
      const column = sortState.column;
      if (sortState.order === 'ascend') {
        return a[column] > b[column] ? 1 : -1;
      }
      return a[column] < b[column] ? 1 : -1;
    });
  };

  return (
    <>
      <style jsx>{`
        .custom-sorter {
          display: inline-flex;
          flex-direction: column;
          margin-left: 8px;
          cursor: pointer;
        }
        .sort-caret {
          color: #c0c4cc;
          transition: color 0.3s;
          font-size: 12px;
        }
        .sort-caret.active {
          color: #1890ff;
        }
        .sort-caret:hover {
          color: #1890ff;
        }
      `}</style>
      <Table 
        columns={columns}
        dataSource={handleTableChange()}
        pagination={false}
        onChange={handleTableChange}
      />
    </>
  );
};

export default CustomTable;
推荐问题
宣传栏