做全国行政区划的展示,包含街道数据有十几万条,全部加载接口比较慢,所以采取了table的懒加载,在新增子节点,编辑删除节点的过程中,官方文档里面并没有相对应的方法,里面遇到了很多坑,这里记录一下实现方法。
1.首先界面如图所示,表格外层有创建按钮,创建的是第一层节点,表格上的添加是指添加子节点,编辑和删除是针对当前节点
<el-table
ref="table"
:loading="loading"
row-key="id"
:default-expand-all="false"
:lazy="true"
:load="load"
:tree-props="treeProps">
<el-table-column
prop="name"
label="行政区划名称"
min-width="200">
</el-table-column>
<el-table-column
prop="code"
label="行政区划代码"
min-width="200">
</el-table-column>
<el-table-column
label="操作"
min-width="200">
<template slot-scope="scope">
<el-button type="text" v-permission="['system:region:edit']" size="mini" @click="edit(scope)">{{$t('app.common.action.edit', {0: ''})}}</el-button>
<span v-if="!scope.row.childrenCount">
<span v-permission="['system:region:delete']"><el-divider direction="vertical"></el-divider></span>
<el-button v-permission="['system:region:delete']" type="text" size="mini" @click="deleteItem(scope)">{{$t('app.common.action.delete', { 0: '' })}}</el-button>
</span>
<span v-permission="['system:region:add']"><el-divider direction="vertical"></el-divider></span>
<el-button v-permission="['system:region:add']" type="text" size="mini" @click="create(scope)">{{$t('app.common.action.add', { 0: '' })}}</el-button>
</template>
</el-table-column>
</el-table>
.js主要逻辑代码 ,说明:与后台约定的最外层的节点的父级节点为-1
<script>
export default {
name: 'RegionIndex',
data () {
return {
currentRow: null,
treeProps: {
children: 'children',
hasChildren: 'childrenCount'
},
dialogCreateOrEdit: {}
};
},
methods: {
getItems (id) {
return new Promise((resolve, reject) => {
//接口相关,根据自己的接口处理
this.api.getList({ parent: id }).then((result) => {
resolve(result);
}).finally(() => {
this.loading = false;
}).catch((e) => {
reject(e);
});
});
},
async load (tree, treeNode, resolve) {
try {
let result = await this.getItems(tree.id);
resolve(result);
}
catch (e) {
this.loading = false;
}
},
handleRowClick (row, event, column) {
this.currentRow = row;
},
//打开新增弹窗
create (scope) {
if (scope) {
this.dialogCreateOrEdit.parentId = scope.row ? scope.row.id : -1;
this.currentRow = scope.row;
}
else {
this.dialogCreateOrEdit.parentId = -1;
}
this.dialogCreateOrEdit.id = null;
this.dialogCreateOrEdit.isShow = true;
},
//打开编辑弹窗
edit (scope) {
this.editItem = scope.row;
this.currentRow = scope.row;
this.dialogCreateOrEdit.parentId = scope.row.parent;
this.dialogCreateOrEdit.id = scope.row.id;
this.dialogCreateOrEdit.isShow = true;
},
//删除
deleteItem (scope) {
const item = scope.row;
this.$confirm(this.$t('app.common.message.deleteWarningMessage', { 0: '' })).then(async (result) => {
if (!result) {
return;
}
// 删除接口,根据自己项目相应处理
await this.api.deleteItem({ id: item.id });
this.deleteLazyTableItem(item); this.$message.success(this.$t('app.common.message.successfullyDeleted'));
});
},
deleteLazyTableItem (item) {
const store = this.$refs.table.store;
if (item.parent != -1) {
const parent = store.states.lazyTreeNodeMap[item.parent];
const index = parent.findIndex(child => child.id == item.id);
parent.splice(index, 1);
}
else {
const parent = store.states.data;
const index = parent.findIndex(child => child.id == item.id);
parent.splice(index, 1);
}
},
//新增,编辑之后的处理,model为新增编辑后的节点data
handleOnSave (model) {
const copy = Object.assign({}, model);
const parentId = this.dialogCreateOrEdit.parentId;
if (this.dialogCreateOrEdit.id) { //编辑
if (model.parent == parentId) { // 未改变父级节点,更新节点数据
Object.assign(this.editItem, copy, {
childrenCount: this.editItem.childrenCount
});
}
else { //改变父级节点了,先删除原始父级节点下的子节点,再去对应的父级节点添加子节点
this.deleteLazyTableItem(this.editItem);
this.addLazyTableItem(model.parent, copy);
}
}
else {//添加节点
this.addLazyTableItem(parentId, copy);
}
},
addLazyTableItem (parentId, copy) {
const store = this.$refs.table.store;
const parentRow = store.states.data.find(item => item.id === parentId);
if (parentId != -1) {
const parentTreeNode = store.states.treeData[parentId];
if (parentTreeNode) {
if (parentTreeNode.loaded) {
store.states.lazyTreeNodeMap[parentId].push(copy);
}
else {
store.loadOrToggle(parentRow);
}
}
else {
store.states.treeData[parentId] = {
loading: false,
loaded: false,
expanded: false,
children: [],
lazy: true,
level: ''
};
store.loadOrToggle(parentRow);
}
}
else {
store.states.data.push(copy);
}
}
}
};
</script>