最近在數據源管理功能,需要以樹的形式異步展現:

根節點可以新增目錄。
目錄節點可以新增目錄,編輯目錄,新增主數據。
主數據節點無操作按鈕。
找到element-ui的官方文檔,el-tree。(地址:http://element-cn.eleme.io/#/zh-CN/component/tree )

結合自定義節點內容:

1.節點后添加操作按鈕
renderContent(h, { node, data }) {
return (
<span class="custom-tree-node">
<span>{node.label}</span>
<span>
<i
v-show={
node.level == 1 || data.nodeType == FunctionNodeType.BizFolder
}
class="el-icon-plus"
title="新增目錄"
on-click={() => this.editBizFolder(node, "add", resolve)}
/>
<i
v-show={data.nodeType == FunctionNodeType.BizFolder}
class="el-icon-edit"
title="編輯目錄"
on-click={() => this.editBizFolder(node, "edit")}
/>
<i
v-show={data.nodeType == FunctionNodeType.BizFolder}
class="el-icon-document"
title="添加主數據"
on-click={() => this.addBizObject(node)}
/>
</span>
</span>
);
}
2. 默認根節點是展開的
<el-tree
:data="data"
:props="defaultProps"
:highlight-current="true"
:load="loadDataTree"
lazy
:expand-on-click-node="false"
:render-content="renderContent"
node-key="id"
:default-expanded-keys="['1']"
@node-click="nodeClick"
></el-tree>
標紅處為關鍵代碼
3. 動態添加,更新后刷新節點
append方法肯定是不行的,添加完成后,需要重新拉取查詢子節點的接口,這個方法放棄了,
緩存resolve方法,這個方法也是不可取的,this的指向會發生問題(展開節點a再點擊b節點的新增目錄),這個方法也必須得放棄。
element-ui提供了 doCreateChildren(children, defaultProps)方法創建子節點
children就是你需要動態添加的數據。
reloadNode(node) {
DataSourceService.getDataTree(node.data.objectId).then(
res => {
if (res.data && res.data.length > 0) {
let rootChildren = [];
res.data.forEach(element => {
rootChildren.push({
name: element.Text,
leaf: element.IsLeaf,
objectId: element.ObjectID,
code: element.Code,
nodeType: element.NodeType,
sortKey: element.SortKey,
children: []
});
});
node.childNodes = []; //清空節點
node.doCreateChildren(rootChildren); //更新節點
}
}
)
4.最終代碼
<!-- 外部數據源 -->
<template>
<div id="master-data">
<div class="master-data-tree">
<el-tree
:data="data"
:props="defaultProps"
:highlight-current="true"
:load="loadDataTree"
lazy
:expand-on-click-node="false"
:render-content="renderContent"
node-key="id"
:default-expanded-keys="['1']"
@node-click="nodeClick"
></el-tree>
</div>
<div class="master-data-info">
</div>
</div>
</template>
<script>
import DataSourceService from "@/services/data-source.service";
import FunctionNodeType from "@/models/data-source/function-node-type.js";
export default {
name: "master-data",
data() {
return {
defaultProps: {
children: "children",
label: "name",
isLeaf: "leaf"
}
};
},
components: {
},
computed: {},
methods: {
loadDataTree(node, resolve) {
if (node.level === 0) {
return resolve([{ id: "1", name: "主數據", objectId: "" }]);
}
DataSourceService.getDataTree(node.data.objectId).then(
res => {
if (!res.status) {
return;
}
let rootChildren = [];
if (res.data && res.data.length > 0) {
res.data.forEach(element => {
rootChildren.push({
name: element.Text,
leaf: element.IsLeaf,
objectId: element.ObjectID,
code: element.Code,
nodeType: element.NodeType,
sortKey: element.SortKey,
children: []
});
});
}
if (resolve) {
resolve(rootChildren); //動態加載時
} else {
//更新節點時:
node.childNodes = [];
node.doCreateChildren(rootChildren);
}
}
);
},
renderContent(h, { node, data }) {
return (
<span class="custom-tree-node">
<span>{node.label}</span>
<span>
<i
v-show={
node.level == 1 || data.nodeType == FunctionNodeType.BizFolder
}
class="el-icon-plus"
title="新增目錄"
on-click={() => this.editBizFolder(node, "add", resolve)}
/>
<i
v-show={data.nodeType == FunctionNodeType.BizFolder}
class="el-icon-edit"
title="編輯目錄"
on-click={() => this.editBizFolder(node, "edit")}
/>
<i
v-show={data.nodeType == FunctionNodeType.BizFolder}
class="el-icon-document"
title="添加主數據"
on-click={() => this.addBizObject(node)}
/>
</span>
</span>
);
},
editBizFolder(node, type) {
// 新增編輯目錄
event.stopPropagation(); // 阻止冒泡給nodeClick
const data = node.data;
const parentData = node.parent.data;
const title = type == "add" ? "新增目錄" : "編輯目錄";
//...彈窗邏輯,保存后回調
const refreshNode = type == "add" ? node : node.parent;
this.loadDataTree(refreshNode); //刷新節點
},
nodeClick(data) {
debugger;
// 點擊樹
}
}
};
</script>
<style>
.custom-tree-node {
flex: 1;
display: flex;
align-items: center;
justify-content: space-between;
font-size: 14px;
padding-right: 8px;
}
.custom-tree-node i {
margin-left: 10px;
}
#master-data {
height: 100%;
flex: 1;
flex-direction: row;
display: flex;
}
.master-data-tree {
width: 270px;
border-right: 1px solid #dcdfe6;
}
.master-data-info {
width: 100%;
margin-left: 20px;
}
</style>
另el-tree的一些基本方法...
(可參考element-ui源碼node_modules\element-ui\packages\tree\src\model\node.js 和tree-store.js)
1.設置展開和收縮
if (!node.expanded) {
node.expand();
} else {
node.collapse();
}
2.獲取父節點
node.parent
