最近在數據源管理功能,須要以樹的形式異步展示:javascript
根節點能夠新增目錄。java
目錄節點能夠新增目錄,編輯目錄,新增主數據。node
主數據節點無操做按鈕。element-ui
找到element-ui的官方文檔,el-tree。(地址:http://element-cn.eleme.io/#/zh-CN/component/tree )緩存
結合自定義節點內容:app
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. 默認根節點是展開的flex
<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>
標紅處爲關鍵代碼ui
3. 動態添加,更新後刷新節點this
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)
if (!node.expanded) { node.expand(); } else { node.collapse(); }
2.獲取父節點
node.parent