feat: 前端组件准备
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
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 = <T>(
|
||||
dataRef: Ref<T[]>,
|
||||
defaultSortColumn: MaybeRefOrGetter<string> = "", // 默认排序列的key值,可以让某一列默认排序
|
||||
defaultSortDirection: MaybeRefOrGetter<"asc" | "desc" | ""> = "asc", // 为空表示不排序
|
||||
columnsRef?: Ref<SortableColumn[]> // 列配置,用于获取 zeroAsNull 等配置
|
||||
) => {
|
||||
// 排序状态
|
||||
const sortColumn = ref<string>(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
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user