elementUI table 多列排序并保持状态样式显示正确(无需修改源码)

问题:

最近碰到需要用el-table做多个排序字段的需求,但是碰到一个样式问题,就是每次点击一个排序字段,表格上其他的排序字段样式就会被清掉,导致实际传给接口的值还是包含了多个排序字段,但页面显示只会显示一个排序字段,如下

解决:

在网络查阅众多方法后,还是取得了一个较为合适的解决方案,具体看链接

https://blog.51cto.com/u_11666747/5335468?

方便再次翻阅的时候理解,这里简单理一下实现的逻辑

1.处理sort-change方法

点击排序按钮后会触发此方法,此时的sortChange作为点击排序按钮后自定义multiOrder属性的方法,multiOrder是自定义属性名,用于后续赋值给order属性

javascript 复制代码
 // 列表排序
        sortChange ({ column, prop, order }) {
            // 有些列不需要排序,提前返回
            if (column.sortable !== "custom") {
                return;
            }
            if (!column.multiOrder) {
                column.multiOrder = "descending";
            } else if (column.multiOrder === "descending") {
                column.multiOrder = "ascending";
            } else {
                column.multiOrder = "";
            }
            this.handleOrderChange(column.property, column.multiOrder);
        },
        // 点击排序箭头 
        handleOrderChange (sortName, sortType) {
            if (!sortType) {
                this.sortParams = this.sortParams.filter(
                    (item) => {
                        return item.sortName !== sortName;
                    }
                );
            } else {
                let result = this.sortParams.find(
                    (e) => e.sortName === sortName
                );
                if (result) {
                    result.sortType = sortType == "descending" ? "desc" : "asc";
                } else {
                    this.sortParams.push({
                        sortName: sortName,
                        sortType: sortType == "descending" ? "desc" : "asc",
                    });
                }
            }
            //这里是处理    
            let sortStr = this.buildSortParams()
            this.$nextTick(() => {
                this.$emit("sort-change", sortStr);
                this.$emit("sortChange", sortStr);
                this.$emit("sortchange", sortStr);
            })
        },

2.绑定headerCellClassName方法

javascript 复制代码
<el-table  :header-cell-class-name="headerCellClassName"></el-table>

headerCellClassName ({ column }) {
            // 只有当 multiOrder 存在时才覆盖 order
            if (column.multiOrder !== undefined) {
                column.order = column.multiOrder;
            }
        },

这步是为了在每次渲染表头时重新把multiOrder赋值给column对象中的order属性(赋值给order的意义在于让状态样式能够正确显示)

之所以要这样做,是因为el-table默认为单列排序,在element的源码文件table-header.js里handleSortClick方法有这样一段代码,会导致当点击新列时,会清除之前排序列的 order 状态

javascript 复制代码
if (sortingColumn !== column || (sortingColumn === column && sortingColumn.order === null)) {
    if (sortingColumn) {
        sortingColumn.order = null;  // 清除之前的排序列状态
    }
    states.sortingColumn = column;   // 设置新的排序列
    sortProp = column.property;
}

所以multiOrder就相当于一个存储在column对象中一个独立的状态,不会被源码中的这段代码给清除掉,也就顺利保留了之前的状态,无论源来的逻辑怎么清order这个属性,在渲染表头时又会触发headerCellClassName,让multiOrder重新赋值给order

仅记录,有不对也欢迎指出

相关推荐
华玥作者14 小时前
[特殊字符] VitePress 对接 Algolia AI 问答(DocSearch + AI Search)完整实战(下)
前端·人工智能·ai
Mr Xu_14 小时前
告别冗长 switch-case:Vue 项目中基于映射表的优雅路由数据匹配方案
前端·javascript·vue.js
前端摸鱼匠14 小时前
Vue 3 的toRefs保持响应性:讲解toRefs在解构响应式对象时的作用
前端·javascript·vue.js·前端框架·ecmascript
lang2015092814 小时前
JSR-340 :高性能Web开发新标准
java·前端·servlet
好家伙VCC15 小时前
### WebRTC技术:实时通信的革新与实现####webRTC(Web Real-TimeComm
java·前端·python·webrtc
未来之窗软件服务16 小时前
未来之窗昭和仙君(六十五)Vue与跨地区多部门开发—东方仙盟练气
前端·javascript·vue.js·仙盟创梦ide·东方仙盟·昭和仙君
嘿起屁儿整16 小时前
面试点(网络层面)
前端·网络
VT.馒头16 小时前
【力扣】2721. 并行执行异步函数
前端·javascript·算法·leetcode·typescript
phltxy17 小时前
Vue 核心特性实战指南:指令、样式绑定、计算属性与侦听器
前端·javascript·vue.js
Byron070718 小时前
Vue 中使用 Tiptap 富文本编辑器的完整指南
前端·javascript·vue.js