export interface SortableColumn { key?: string; slot?: string; prop?: string | ((index: number) => number); name?: string; // 列的显示名称 sortable?: boolean; // 是否可排序 zeroAsNull?: boolean; // 是否将 0 视为 null 值处理 [key: string]: any; } // 可排序表格的函数 export const useSortableTable = ( dataRef: Ref, defaultSortColumn: MaybeRefOrGetter = "", // 默认排序列的key值,可以让某一列默认排序 defaultSortDirection: MaybeRefOrGetter<"asc" | "desc" | ""> = "asc", // 为空表示不排序 columnsRef?: Ref // 列配置,用于获取 zeroAsNull 等配置 ) => { // 排序状态 const sortColumn = ref(toValue(defaultSortColumn)); const sortDirection = ref<"asc" | "desc" | "">( toValue(defaultSortColumn) ? toValue(defaultSortDirection) : "" ); // 监听默认排序参数的变化 watchEffect(() => { const newColumn = toValue(defaultSortColumn); sortColumn.value = newColumn; sortDirection.value = newColumn ? toValue(defaultSortDirection) : ""; }); // 排序处理函数 const handleSort = (column: SortableColumn) => { if (!column.sortable) return; const columnKey = column.key || column.slot || column.prop; if (!columnKey || typeof columnKey !== "string") return; if (sortColumn.value === columnKey) { // 当前列被点击:升序 -> 降序 -> 取消排序 if (sortDirection.value === "asc") { // 如果是升序,改为降序 sortDirection.value = "desc"; } else if (sortDirection.value === "desc") { // 如果是降序,取消排序 sortColumn.value = ""; sortDirection.value = ""; } else { // 如果是不排序,设置为升序 sortDirection.value = "asc"; } } else { // 如果点击的是新列,设置为升序 sortColumn.value = columnKey; sortDirection.value = "asc"; } }; // 计算排序后的数据 const getSortedData = computed(() => { const data = dataRef.value || []; if (!sortColumn.value || !sortDirection.value) return data; // 查找当前排序列的配置 const currentColumn = columnsRef?.value?.find( (col) => (col.key || col.slot || col.prop) === sortColumn.value ); return [...data].sort((a: any, b: any) => { let aValue = a[sortColumn.value]; let bValue = b[sortColumn.value]; const factor = sortDirection.value === "asc" ? 1 : -1; // 如果配置了 zeroAsNull,将 0 视为 null if (currentColumn?.zeroAsNull) { if (aValue === 0) aValue = null; if (bValue === 0) bValue = null; } // 处理 null 和 undefined 值 if (aValue == null && bValue == null) return 0; if (aValue == null) return 1; if (bValue == null) return -1; // 根据数据类型进行排序 if (typeof aValue === "number" && typeof bValue === "number") { return (aValue - bValue) * factor; } else { // 字符串或其他类型 return String(aValue).localeCompare(String(bValue)) * factor; } }); }); return { sortColumn, sortDirection, handleSort, sortedData: getSortedData }; };