背景:这次做了一个无限可拓展的树形表格,积累到了一些小tips
图:
表存储结构:必须字段: id、parent_id、ancestors(祖级列表)
后端把节点对应的父级关系存储,
父级是主题、子级是指标;这里不同的主题是不同的根节点,parent_id 我存的‘0’;子级的parent_id对应父级的‘id’;
构造树的算法是在前端【handleTree】实现的
<el-table
v-if="refreshTable"
:data="measureRelatedList"
row-key="id"
:default-expand-all="isExpandAll"
v-loading="loading"
:tree-props="{children: 'children', hasChildren: 'hasChildren'}"
>
<el-table-column prop="measureName" label="主题/指标名称" width="260"></el-table-column>
<el-table-column prop="根据需求设计 label="根据需求设计" width="260"></el-table-column>
<el-table-column label="创建时间" align="center" prop="createTime" width="200">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
>修改
</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-plus"
@click="handleAdd(scope.row)"
>新增
</el-button>
<el-button
v-if="scope.row.parentId != 0"
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
>删除
</el-button>
</template>
</el-table-column>
</el-table>
created() {
this.getList();
},
methods: {
/** 查询指标列表 */
getList() {
this.loading = true;
listMeasureDiagnose(this.queryParams).then(response => {
this.measureRelatedList = this.handleTree(response.data, "id");
this.loading = false;
});
},
}
/**
* 构造树型结构数据
* @param {*} data 数据源
* @param {*} id id字段 默认 'id'
* @param {*} parentId 父节点字段 默认 'parentId'
* @param {*} children 孩子节点字段 默认 'children'
*/
export function handleTree(data, id, parentId, children) {
let config = {
id: id || 'id',
parentId: parentId || 'parentId',
childrenList: children || 'children'
};
var childrenListMap = {};
var nodeIds = {};
var tree = [];
for (let d of data) {
let parentId = d[config.parentId];
if (childrenListMap[parentId] == null) {
childrenListMap[parentId] = [];
}
nodeIds[d[config.id]] = d;
childrenListMap[parentId].push(d);
}
for (let d of data) {
let parentId = d[config.parentId];
if (nodeIds[parentId] == null) {
tree.push(d);
}
}
for (let t of tree) {
adaptToChildrenList(t);
}
function adaptToChildrenList(o) {
if (childrenListMap[o[config.id]] !== null) {
o[config.childrenList] = childrenListMap[o[config.id]];
}
if (o[config.childrenList]) {
for (let c of o[config.childrenList]) {
adaptToChildrenList(c);
}
}
}
return tree;
}