SortMixin.js 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. /**
  2. * 通用多列排序 Mixin
  3. *
  4. * 点击列头行为:
  5. * - 首次点击:升序 ↑
  6. * - 再次点击:降序 ↓
  7. * - 第三次点击:取消排序
  8. * - 点击其他列:追加为次级排序(多列排序)
  9. *
  10. * 用法:在页面 data() 中声明 sortableColumns,在 loadList() 中调用 applySortToParams(params)。
  11. */
  12. export default {
  13. data() {
  14. return {
  15. sortState: [], // [{column, order:'asc'|'desc'}]
  16. }
  17. },
  18. computed: {
  19. sortLabel() {
  20. if (!this.sortState || this.sortState.length === 0) return ''
  21. const labels = this.sortableColumns || {}
  22. return this.sortState.map(s => {
  23. const label = labels[s.column] || s.column
  24. return (s.order === 'asc' ? label + '↑' : label + '↓')
  25. }).join(' > ')
  26. }
  27. },
  28. methods: {
  29. sortClass(col) {
  30. const s = this.sortState.find(x => x.column === col)
  31. if (!s) return ''
  32. return s.order === 'asc' ? 'sort-asc' : 'sort-desc'
  33. },
  34. sortIcon(col) {
  35. const s = this.sortState.find(x => x.column === col)
  36. if (!s) return ''
  37. return s.order === 'asc' ? ' ↑' : ' ↓'
  38. },
  39. /** 返回当前列在 sortState 中的排序序号(从1开始),未排序返回 null */
  40. sortIndex(col) {
  41. const idx = this.sortState.findIndex(s => s.column === col)
  42. return idx >= 0 ? idx + 1 : null
  43. },
  44. onSortClick(col) {
  45. const idx = this.sortState.findIndex(s => s.column === col)
  46. if (idx >= 0) {
  47. // 已在排序中:cycle asc → desc → remove
  48. if (this.sortState[idx].order === 'asc') {
  49. this.sortState[idx].order = 'desc'
  50. } else {
  51. this.sortState.splice(idx, 1)
  52. }
  53. } else {
  54. // 新列:追加到排序末尾(多列排序)
  55. this.sortState.push({ column: col, order: 'asc' })
  56. }
  57. this.reloadAfterSort()
  58. },
  59. onSortToggle(col) {
  60. const idx = this.sortState.findIndex(s => s.column === col)
  61. if (idx >= 0) {
  62. this.sortState.splice(idx, 1)
  63. } else {
  64. this.sortState.push({ column: col, order: 'asc' })
  65. }
  66. this.reloadAfterSort()
  67. },
  68. reloadAfterSort() {
  69. if (typeof this.loadList === 'function') {
  70. this.loadList()
  71. } else if (typeof this.loadData === 'function') {
  72. this.loadData()
  73. } else if (typeof this.loadTasks === 'function') {
  74. this.loadTasks()
  75. } else if (typeof this.loadPlans === 'function') {
  76. this.loadPlans()
  77. }
  78. },
  79. clearSort() {
  80. this.sortState = []
  81. if (typeof this.loadList === 'function') this.loadList()
  82. },
  83. applySortToParams(params) {
  84. if (this.sortState.length > 0) {
  85. params.sort = this.sortState
  86. }
  87. return params
  88. }
  89. }
  90. }