公司最近有个需求优化,el-table的树形表格,结合复选框,在数据量大的情况下,会导致整个页面卡顿,且勾选全选功能时,间隔几秒才能响应。忍无可忍,于是疯狂找百度,寻找好的组件使用。终于给我找到了一套好用的组件,优化了 el-table+树形+复选框(快速渲染,点击复选框不会卡顿)。
先上官网:
Vxe Table v4https://vxetable.cn/#/component/table/scroll/tree具体页面效果:
注意(踩坑):
刚开始我是跟着官网安装最新版本,最新版本好像出现些问题,点击全选全部勾选上,再点击取消某个最内层子级复选框时,父级按钮确实变为半选状态,但是父级以上的层级就会出现问题,并不会变为半选状态。
解决方案:
于是我还是用回了稳定的版本,如果您不在意这个细节的话也可以使用最新版本,以下附上我的使用版本:
这里我介绍主要的几个属性:
属性 | 说明 | 数据类型 |
checkbox-config | 复选框配置项 | object |
checkbox-config.checkField | 绑定选中属性(行数据中必须存在该字段,否则无效) | string |
checkbox-config.checkMethod | 是否允许勾选的方法,该方法,的返回值用来决定这一行的 checkbox 是否可以勾选 | ({ row }) => boolean |
属性 | 说明 | 数据类型 |
tree-config | 树形结构配置项 | object |
tree-config.transform | 自动将列表转为树结构(支持虚拟滚动) | boolean |
tree-config.parentField | 用于 tree-config.transform,树父节点的字段名 | string |
属性 | 说明 | 数据类型 |
scroll-y | 纵向滚动配置 | object |
scroll-y.enabled | 是否启用 | boolean |
scroll-y.gt | 指定大于指定行时自动启动纵向虚拟滚动,如果为 0 则总是启用;如果需要关闭,可以设置 enabled 为 false(注:启用纵向虚拟滚动之后将不能支持动态行高) | number |
事件名 | 说明 |
checkbox-change | 只对 type=checkbox 有效,当手动勾选并且值发生改变时触发的事件 |
checkbox-all | 只对 type=checkbox 有效,当手动勾选全选时触发的事件 |
当点击全选或勾选某个时,我们可以获得已选中的行数据,数据格式如下,我们可以获取records字段即可获取已选中的行数据:
注意data属性接收的数据结构是一维数据,一般后端返回给我们的都是树形结构的数组,我们拿到还需要将其扁平化
主要代码:
html:
<vxe-tableref="vxeTable"show-overflowempty-text="暂无数据":header-cell-style="{background: '#EFF0F2',color: '#1A1E25',fontWeight: 400,}":row-config="{isHover: true,}":checkbox-config="{checkField: 'transferStatus',checkMethod: checkboxCheckMethod,}":tree-config="{parentField: 'parentId',iconClose: 'el-icon-arrow-right',iconOpen: 'el-icon-arrow-down',transform: true,}":scroll-y="{enabled: true,gt: 0,}":data="tableData":min-height="100":max-height="700"border="inner"@checkbox-change="handleCheckboxChange"@checkbox-all="handleCheckboxChange"
><vxe-columnfield="name"title="移交目录清单":tree-node="true"min-width="100"/><vxe-columntitle="最近移交时间"field="transferTime"align="center"/><vxe-columntype="checkbox"title="是否移交"width="120"align="center"/>
</vxe-table>
js:
checkboxCheckMethod({ row }) {if (this.disabled) {return false}return true
},
handleCheckboxChange(data) {this.selectionList = data.records
},
// 展开所有
expandTree() {this.$refs.vxeTable.setAllTreeExpand(true)
},
flattenTreeData(treeData, result = []) {for (let i = 0; i < treeData.length; i++) {const node = treeData[i]result.push(node) // 将当前节点添加到结果数组中if (node.children && node.children.length > 0) {this.flattenTreeData(node.children, result) // 递归处理子节点}}return result
}