1. 程式人生 > >Vue:eliment-ui el-tree動態加載更新

Vue:eliment-ui el-tree動態加載更新

必須 aso title 發生 完成後 tween ron 回調 parent

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

技術分享圖片

根節點可以新增目錄。

目錄節點可以新增目錄,編輯目錄,新增主數據。

主數據節點無操作按鈕。

找到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.jstree-store.js

1.設置展開和收縮
 if (!node.expanded) {
     node.expand();
 } else {
     node.collapse();
 }

2.獲取父節點

node.parent

  

Vue:eliment-ui el-tree動態加載更新