/** * 通用多列排序 Mixin * * 点击列头行为: * - 首次点击:升序 ↑ * - 再次点击:降序 ↓ * - 第三次点击:取消排序 * - 点击其他列:追加为次级排序(多列排序) * * 用法:在页面 data() 中声明 sortableColumns,在 loadList() 中调用 applySortToParams(params)。 */ export default { data() { return { sortState: [], // [{column, order:'asc'|'desc'}] } }, computed: { sortLabel() { if (!this.sortState || this.sortState.length === 0) return '' const labels = this.sortableColumns || {} return this.sortState.map(s => { const label = labels[s.column] || s.column return (s.order === 'asc' ? label + '↑' : label + '↓') }).join(' > ') } }, methods: { sortClass(col) { const s = this.sortState.find(x => x.column === col) if (!s) return '' return s.order === 'asc' ? 'sort-asc' : 'sort-desc' }, sortIcon(col) { const s = this.sortState.find(x => x.column === col) if (!s) return '' return s.order === 'asc' ? ' ↑' : ' ↓' }, /** 返回当前列在 sortState 中的排序序号(从1开始),未排序返回 null */ sortIndex(col) { const idx = this.sortState.findIndex(s => s.column === col) return idx >= 0 ? idx + 1 : null }, onSortClick(col) { const idx = this.sortState.findIndex(s => s.column === col) if (idx >= 0) { // 已在排序中:cycle asc → desc → remove if (this.sortState[idx].order === 'asc') { this.sortState[idx].order = 'desc' } else { this.sortState.splice(idx, 1) } } else { // 新列:追加到排序末尾(多列排序) this.sortState.push({ column: col, order: 'asc' }) } this.reloadAfterSort() }, onSortToggle(col) { const idx = this.sortState.findIndex(s => s.column === col) if (idx >= 0) { this.sortState.splice(idx, 1) } else { this.sortState.push({ column: col, order: 'asc' }) } this.reloadAfterSort() }, reloadAfterSort() { if (typeof this.loadList === 'function') { this.loadList() } else if (typeof this.loadData === 'function') { this.loadData() } else if (typeof this.loadTasks === 'function') { this.loadTasks() } else if (typeof this.loadPlans === 'function') { this.loadPlans() } }, clearSort() { this.sortState = [] if (typeof this.loadList === 'function') this.loadList() }, applySortToParams(params) { if (this.sortState.length > 0) { params.sort = this.sortState } return params } } }