useColumnSort.ts 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. import { computed, ref, watch, type Ref } from 'vue'
  2. export type SortOrder = 'asc' | 'desc'
  3. export function nextSortState(
  4. currentField: string | null,
  5. currentOrder: SortOrder | null,
  6. prop: string,
  7. order: SortOrder
  8. ): { sortField: string | null; sortOrder: SortOrder | null } {
  9. if (currentField === prop && currentOrder === order) {
  10. return { sortField: null, sortOrder: null }
  11. }
  12. return { sortField: prop, sortOrder: order }
  13. }
  14. export function useColumnSort(options?: { onChange?: () => void }) {
  15. const sortField = ref<string | null>(null)
  16. const sortOrder = ref<SortOrder | null>(null)
  17. const hasActiveSort = computed(() => Boolean(sortField.value && sortOrder.value))
  18. function setSort(prop: string, order: SortOrder) {
  19. const next = nextSortState(sortField.value, sortOrder.value, prop, order)
  20. sortField.value = next.sortField
  21. sortOrder.value = next.sortOrder
  22. options?.onChange?.()
  23. }
  24. function clearSort() {
  25. if (!sortField.value && !sortOrder.value) return
  26. sortField.value = null
  27. sortOrder.value = null
  28. options?.onChange?.()
  29. }
  30. function isSortActive(prop: string, order?: SortOrder) {
  31. if (!sortField.value || sortField.value !== prop) return false
  32. if (order == null) return true
  33. return sortOrder.value === order
  34. }
  35. function toQueryParams(): Record<string, string> {
  36. if (!sortField.value || !sortOrder.value) return {}
  37. return { sortField: sortField.value, sortOrder: sortOrder.value }
  38. }
  39. function onColumnHidden(prop: string) {
  40. if (sortField.value === prop) clearSort()
  41. }
  42. function watchVisibleColumns(visibleProps: Ref<string[]>) {
  43. watch(
  44. visibleProps,
  45. (next, prev) => {
  46. if (!prev) return
  47. const nextSet = new Set(next || [])
  48. for (const p of prev) {
  49. if (!nextSet.has(p)) onColumnHidden(p)
  50. }
  51. },
  52. { deep: true }
  53. )
  54. }
  55. return {
  56. sortField,
  57. sortOrder,
  58. hasActiveSort,
  59. setSort,
  60. clearSort,
  61. isSortActive,
  62. toQueryParams,
  63. onColumnHidden,
  64. watchVisibleColumns
  65. }
  66. }