一个懒加载的树状表格实例
实现一个树状表格,需要用到vxe-table这个库,虽然element-ui也能实现,但这个库是专门针对表格做了更多的拓展,功能更多一些。
接下来,说一下使用方式。
安装
npm install xe-utils vxe-table
// 入口文件引入,一般是main.js import Vue from 'vue' import 'xe-utils' import VXETable from 'vxe-table' import 'vxe-table/lib/index.css'
Vue.use(VXETable)
// 给 vue 实例挂载全局窗口对象,属性名称随意定义,例如:$XModal // Vue.prototype.$modal = VXETable.modal
模板
要实现懒加载,tree-config配置参数如下:
lazy
: 懒加载hasChild
: 是否有子节点,值应为布尔值。为true则加载childrenchildren
: 映射的要加载的子节点集合loadMethod
: 实现加载子节点的方式
js代码
export default { data() { return { tableData: [], loading: false }; }, mounted() { // this.tableData = window.MOCK_TREE_DATA_LIST; this.$bus.$on('send', data => { this.tableData = [data]; }); }, methods: { selectChangeEvent({ records }) { // checkbox选中事件 console.info(`勾选${records.length}个树形节点`, records); }, formatStatus({ cellValue, row, column }) { // 格式化方法 return XEUtils.toDateString(cellValue, 'yyyy-MM-dd HH:ss:mm') }, loadChildrenMethod({ row }) { // 加载子节点 /** * @desc: 这里必须返回一个promise对象,把结果通过resolve返回。 * 因为源码返回的是一个promise,如果我们的结果不是promise就会报错。 * `xxxx catch is undefind` cathc的报错。 * 当时脑阔痛了好久。 */ return new Promise((resolve, reject) => { this.$axios .get(`/test/mdporg/workWeixin/queryChildrens?id=${row.id}`) .then(res => { let arr = res.data.childrens; resolve(arr); }); }); } } };
使用el-table懒加载树形表格时的注意点
先放个简单的el-table例子
1、版本问题
el-table懒加载执行两次,loading未取消的bug,后面升级版本即可。不升级的情况下可以如下面处理。
mounted() { // 2.15.3 版本修复了这个bug, 目前版本没有更新 https://github.com/ElemeFE/element/pull/21041 this.$refs.refTable.store.loadData = function(row, key, treeNode){ const { load } = this.table; const { treeData: rawTreeData } = this.states; if (load && !rawTreeData[key].loaded) { rawTreeData[key].loading = true; load(row, treeNode, data => { if (!Array.isArray(data)) { throw new Error('[ElTable] data must be an array'); } const { lazyTreeNodeMap, treeData } = this.states; // 修复快速切换数据时报错 if(!treeData[key]) { return } treeData[key].loading = false; treeData[key].loaded = true; treeData[key].expanded = true; if (data.length) { this.$set(lazyTreeNodeMap, key, data); } this.table.$emit('expand-change', row, true); }); } } },
2、数据显示
1.tableData是开始时的数据,后面load懒加载的数据都不会在tableData中
2.设置tableData=[],并没有清空树里面的数据,如果下次懒加载返回的是空数组,但页面上会显示上一次的数据。(如果你这个时候点击下载数据,就会出现下载的内容跟表格显示的不一致)
resetLazyTree() { // 单独设置这个是无效的,大坑~ 一定要清空孩子,否则loadOrgTable返回数据在没有孩子的情况下会显示上次的孩子节点 this.tableData = [] this.$set(this.$refs.refTable.store.states, 'lazyTreeNodeMap', {}) },
3.有时表格下方多出一行空白, 或者树形表格加载子节点时,可能出现滚动条,导致行错位。
都可以尝试重新刷新表格布局
// 对 Table 进行重新布局 refreshTableLayout() { this.$nextTick(() => { this.$refs.refTable.doLayout() }) },
3、滚动条
不去改这个默认滚动条的样式,会少很多问题。。。。
比如改变了滚动条的宽为现在的一半,那么会出现最后一行的第一列文字被挡住一半。
这个先放着,有好的解决办法再来。。。
4、数据结构
像这种双表头的表格,数据结构可以如下:
this.tableData = [{ orgId: 1, orgName: '银行境内机构汇总', hasChildren: true, indData: [ { name:"名字1", a: '--', b: '--', }, { name:"2", a: '--', b: '--', }, ], children: [], }]
如果名字栏的表头先渲染,那么接口indData里面的顺序一定要跟着名字的顺序,否则会出现数据错乱。
5、el-table的fixed导致的问题
场景:使用excelJs 的DOM类型下载来下载表格中的数据, 在获取el-table下载数据后,发现sheet页中有两份相同的数据。
原因:设置了fixed后,el-table渲染的结构中有两个table
解决办法:通过$refs获取到虚拟dom,删除第二个表的dom即可, 这里不能获取真实的dom, 否则页面受到影响。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。