MDC Web Datatable组件实现分页排序后重绘样式异常
MDC DataTable 重绘样式异常排查方案
出现排序/分页触发重绘后样式错乱,90%的情况都是以下几个原因,按顺序排查即可:
- 重绘DOM后未正确处理组件实例绑定:MDC组件和DOM节点是强绑定关系,如果你全量替换了整个表格的DOM节点,必须先调用旧实例的
destroy()方法销毁绑定,再对新的表格DOM重新初始化MDCDataTable实例;如果只替换表体内容,不需要重新初始化,但是必须调用实例的layout()方法触发组件重新计算列宽、对齐等布局参数。 - 重绘时丢失了MDC要求的固定类名或DOM结构:检查重绘后的节点,表头单元格必须保留
mdc-data-table__header-cell类,排序状态对应的mdc-data-table__header-cell--sorted-ascending/mdc-data-table__header-cell--sorted-descending类要和当前排序状态匹配;表体行要加mdc-data-table__row类,单元格要加mdc-data-table__cell类;表头内的排序图标节点(类名mdc-data-table__sort-icon)、行复选框等MDC自动注入的辅助节点不能被误删,很多人重绘时直接把单元格innerHTML替换成纯文本,删掉了这些内置节点,直接会导致间距、对齐异常。 - 检查是否重复初始化组件:同一个DOM节点多次
new MDCDataTable()会导致事件重复绑定、样式类名重复添加,也会出现显示异常。
排序、分页功能正确实现方式
MDC DataTable本身只提供基础的表格交互能力,排序、分页的业务逻辑需要自行实现,核心原则是尽可能少改动DOM,优先调用官方API,不要手动修改MDC维护的DOM结构和类名。
排序功能实现
- 初始化表格后,通过组件监听官方提供的排序事件,不要自己给表头加点击事件:
import { MDCDataTable } from '@material/data-table'; const tableEl = document.querySelector('.mdc-data-table'); const tableInstance = new MDCDataTable(tableEl); // 监听排序点击事件 tableInstance.listen('MDCDataTable:sorted', (event) => { const { columnId, sortValue } = event.detail; // sortValue 三个可选值:'ascending'(升序)、'descending'(降序)、null(取消排序) // 在这里写自己的排序逻辑:如果是前端排序就处理本地数据源,如果是服务端排序就发请求拿排序后的数据 const sortedList = sortYourDataSource(rawDataList, columnId, sortValue); // 只渲染表体部分的内容,不要动表头和表格外层结构 renderTableBody(sortedList); // 重绘完成后必须调用,触发表格重新计算布局 tableInstance.layout(); });
- 渲染表体的函数只需要操作类名为
mdc-data-table__content的表体容器,不要修改表头部分的任何DOM,避免破坏MDC已经绑定好的排序交互和样式结构。
分页功能实现
分页逻辑和排序逻辑基本一致:
- 切换页码、修改每页展示条数时,先拿到当前页需要展示的数据集(前端分页就从本地全量数据里切片,服务端分页就调用接口拿对应页数据)
- 同样只替换
mdc-data-table__content容器内的表体行,保留表头、表格外层结构不变 - 重绘完成后调用
tableInstance.layout()重算布局,如果表格带行选择功能,重绘后需要调用tableInstance.setSelectedRowIds()同步选中状态 - 如果需要展示分页器,配合MDC的按钮、选择器组件自行实现即可,分页器和表格本身没有强绑定关系。
内容的提问来源于stack exchange,提问作者Mani Sundharram
相关产品推荐
相关产品推荐

