ant-design-vue中table组件多列排序

使用前注意

先要确认你使用的antD版本是否支持多列排序,我这里版本是3.2.15,使用的vue3 + ts。

实现效果图

在这里插入图片描述

实现的功能点及相关代码

1. 默认按某几个字段排序

在声明table列时指定需要默认排序的列属性sortOrder(ascend | descend)。 sorter 对象中的multiple字段用于指定多列排序时的优先级。数值越大,优先级越高。这意味着你可以通过为不同的列设置不同的 multiple值来实现多列排序,并且控制它们的排序优先级。

// 处理传值给到接口顺序
let tempSorts = ref<Record<string, any>>([
    { field: 'createTime', order: 'desc' },
    { field: 'name', order: 'desc' },
]);

const columns = ref([
    {
        title: 'ID',
        dataIndex: 'id',
        sorter: {
            multiple: 1,
        },
    },
    {
        title: '设备名称',
        dataIndex: 'name',
        sortOrder: 'descend',
        sorter: {
            multiple: 2,
        },
    },
    {
        title: '产品名称',
        dataIndex: 'productName',
    },
    {
        title: '创建时间',
        dataIndex: 'createTime',
        scopedSlots: true,
        width: 200,
        sortOrder: 'descend',
        sorter: {
            multiple: 3,
        },
    },
    {
        title: '状态',
        dataIndex: 'state',
        scopedSlots: true,
    },
    {
        title: '说明',
        dataIndex: 'describe',
    },
    {
        title: '操作',
        dataIndex: 'action',
        fixed: 'right',
        width: 200,
        scopedSlots: true,
    },
]);

2. 点击排序按钮可同时对多个字段进行排序(按点击顺序传值给到接口)

table组件绑定的方法`@change="onChange"`


/**
 * onChange方法实现:
 * 点击排序图标时处理columns这个数据源中的排序状态sortOrder
 * 首先判断是单列还是多列排序:
 * 1. 若是多列同时排序,sorter为Array,设置对应项的sortOrder属性
 * 2. 若是单列排序,sorter为Object,直接对匹配到的列属性sortOrder赋值。
 * change方法会触发table的查询方法(给接口传的参数在table的查询方法中处理)
 */
const onChange = (pagination, filters, sorter, extra) => {
    if (Object.prototype.toString.call(sorter) === '[object Array]') {
        columns.value.forEach((column) => {
            column.sortOrder = undefined;
            const sorterItem = sorter.find(
                (item) => item.field === column.dataIndex,
            );
            if (sorterItem) {
                // 设置对应项的sortOrder属性
                column.sortOrder = sorterItem.order;
            }
        });

        /**
         * 处理tempSorts.value数据最终按用户点击顺序传递字段到接口
         * 1. 判断排序字段是否已存在,若已存在,则直接更新其排序方式order,否则将当前排序项插入到tempSorts.value中
         */
        sorter.forEach((item) => {
            const index = tempSorts.value.findIndex(
                (param) => param.field === item.field,
            );
            if (index !== -1) {
                tempSorts.value[index].order = item.order;
            } else {
                tempSorts.value.push(item);
            }
        });

        /**
         * 上面是处理①已有字段时更新,②没有字段时插入 的情况
         * 下面处理tempSorts.value数据中③当某个排序字段不参与排序时(sorter中没有这一项时)的情况,即只过滤sorter数据中存在的数据
         */
        tempSorts.value = tempSorts.value.filter((item) => {
            return sorter.some((sorterItem) => sorterItem.field === item.field);
        });
    } else {
        // 当单列排序时,tempSorts.value中只有当前排序列数据(若sorter.order为undefined时标识不参与排序)
        tempSorts.value = [];
        if (sorter.order != undefined) {
            tempSorts.value.push(sorter);
        }

        columns.value.forEach((item) => {
            item.sortOrder = undefined;
            if (item.dataIndex === sorter.field) {
                // 直接对匹配到的列属性sortOrder赋值
                item.sortOrder = sorter.order;
            }
        });
    }
};

3. 点击重置按钮可恢复默认排序状态。

/**
 * 1. 查询和重置调用一个方法,在重置emit触发该方法时多传一个参数resetFlag为true
 * 2. 重置时将排序字段修改为需要默认排序字段,方法resetSort
 */
 
const handleSearch = (_params: any) => {
    const newParams = (_params?.terms as any[])?.map((item1) => {
        item1.terms = item1.terms.map((item2: any) => {
            if (item2.column === 'id$dim-assets') {
                if (item2.termType === 'not') {
                    const oldValue = JSON.parse(item2.value);
                    oldValue.not = true;
                    item2.value = JSON.stringify(oldValue);
                }
                delete item2.termType;
            }

            if (
                item2.column &&
                ['classifiedId', 'accessId', 'accessProvider'].includes(
                    item2.column,
                )
            ) {
                const oldTermType =
                    item2.termType === 'nin' ? 'not' : item2.termType;
                console.log(item2.termType, 'termType');
                delete item2.termType;
                return {
                    ...item2,
                    column: `productId$product-info$${oldTermType}`,
                    value: Array.isArray(item2.value)
                        ? dealSearchValue(item2)
                        : item2.value,
                };
            }
            return item2;
        });
        return item1;
    });

    let sortsParams = tempSorts.value?.map((item) => ({
        name: item?.field,
        order:
            item.order === 'descend'
                ? 'desc'
                : item.order === 'ascend'
                ? 'asc'
                : item.order,
    }));

    params.value = {
        terms: newParams || [],
        sorts: sortsParams,
    };
    if (_params?.resetFlag) {
        resetSort();
    }
};

/**
 * 重置方法
 * 重置时匹配需要重置的列,将当前列sortOrder属性置为需要默认排序值(我这里默认按创建时间和名称倒序)
 */
const resetSort = () => {
    columns.value.forEach((column) => {
        column.sortOrder = undefined; // 取消所有字段排序
        if (column.dataIndex === 'createTime' || column.dataIndex === 'name') {
            column.sortOrder = 'descend';
        }
    });

	// 重置时处理给接口传的数据
    tempSorts.value = [
        { field: 'createTime', order: 'desc' },
        { field: 'name', order: 'desc' },
    ];
};

功能实现完整的关键代码

<template>
    <!-- 上面查询区-代码省略 -->
    <!-- wTable为封装的table组件 -->
    <wTable
        ref="wTableRef"
        :columns="columns"
        :request="query"
        :params="params"
        @change="onChange"
    >
        <!-- 中间省略一些插槽代码 -->
        <!-- 
            上面属性的简单介绍:
            columns:展示的table列
            request: 查询/查询时table数据请求的接口
            params: 查询条件参数与排序字段相关参数
         -->
    </wTable>
</template>
<script setup lang="ts" name="Instance">
import { query } from '@/api/XXX';
const params = ref<Record<string, any>>({});
// 处理传值给到接口顺序
let tempSorts = ref<Record<string, any>>([
    { field: 'createTime', order: 'desc' },
    { field: 'name', order: 'desc' },
]);
const columns = ref([
    {
        title: 'ID',
        dataIndex: 'id',
        sorter: {
            multiple: 1,
        },
    },
    {
        title: '设备名称',
        dataIndex: 'name',
        sortOrder: 'descend',
        sorter: {
            multiple: 2,
        },
    },
    {
        title: '产品名称',
        dataIndex: 'productName',
    },
    {
        title: '创建时间',
        dataIndex: 'createTime',
        scopedSlots: true,
        width: 200,
        sortOrder: 'descend',
        sorter: {
            multiple: 3,
        },
    },
    {
        title: '状态',
        dataIndex: 'state',
        scopedSlots: true,
    },
    {
        title: '说明',
        dataIndex: 'describe',
    },
    {
        title: '操作',
        dataIndex: 'action',
        fixed: 'right',
        width: 200,
        scopedSlots: true,
    },
]);


const onChange = (pagination, filters, sorter, extra) => {
    if (Object.prototype.toString.call(sorter) === '[object Array]') {
        columns.value.forEach((column) => {
            column.sortOrder = undefined;
            const sorterItem = sorter.find(
                (item) => item.field === column.dataIndex,
            );
            if (sorterItem) {
                column.sortOrder = sorterItem.order;
            }
        });

        sorter.forEach((item) => {
            const index = tempSorts.value.findIndex(
                (param) => param.field === item.field,
            );
            if (index !== -1) {
                tempSorts.value[index].order = item.order;
            } else {
                tempSorts.value.push(item);
            }
        });

        tempSorts.value = tempSorts.value.filter((item) => {
            return sorter.some((sorterItem) => sorterItem.field === item.field);
        });
    } else {
        tempSorts.value = [];
        if (sorter.order != undefined) {
            tempSorts.value.push(sorter);
        }

        columns.value.forEach((item) => {
            item.sortOrder = undefined;
            if (item.dataIndex === sorter.field) {
                item.sortOrder = sorter.order;
            }
        });
    }
};

const handleSearch = (_params: any) => {
    const newParams = (_params?.terms as any[])?.map((item1) => {
        item1.terms = item1.terms.map((item2: any) => {
            if (item2.column === 'id$dim-assets') {
                if (item2.termType === 'not') {
                    const oldValue = JSON.parse(item2.value);
                    oldValue.not = true;
                    item2.value = JSON.stringify(oldValue);
                }
                delete item2.termType;
            }

            if (
                item2.column &&
                ['classifiedId', 'accessId', 'accessProvider'].includes(
                    item2.column,
                )
            ) {
                const oldTermType =
                    item2.termType === 'nin' ? 'not' : item2.termType;
                console.log(item2.termType, 'termType');
                delete item2.termType;
                return {
                    ...item2,
                    column: `productId$product-info$${oldTermType}`,
                    value: Array.isArray(item2.value)
                        ? dealSearchValue(item2)
                        : item2.value,
                };
            }
            return item2;
        });
        return item1;
    });

    let sortsParams = tempSorts.value?.map((item) => ({
        name: item?.field,
        order:
            item.order === 'descend'
                ? 'desc'
                : item.order === 'ascend'
                ? 'asc'
                : item.order,
    }));

    params.value = {
        terms: newParams || [],
        sorts: sortsParams,
    };
    if (_params?.resetFlag) {
        resetSort();
    }
};

const resetSort = () => {
    columns.value.forEach((column) => {
        column.sortOrder = undefined;
        if (column.dataIndex === 'createTime' || column.dataIndex === 'name') {
            column.sortOrder = 'descend';
        }
    });

    tempSorts.value = [
        { field: 'createTime', order: 'desc' },
        { field: 'name', order: 'desc' },
    ];
};
</script>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值