Vue:eliment-ui el-tree动态加载更新

最近在数据源管理功能,需要以树的形式异步展现:

根节点可以新增目录。

目录节点可以新增目录,编辑目录,新增主数据。

主数据节点无操作按钮。

找到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 {
   270px;
  border-right: 1px solid #dcdfe6;
}
.master-data-info {
   100%;
  margin-left: 20px;
}
</style>

  

另el-tree的一些基本方法...

(可参考element-ui源码node_moduleselement-uipackages reesrcmodel ode.jstree-store.js

1.设置展开和收缩
 if (!node.expanded) {
     node.expand();
 } else {
     node.collapse();
 }

2.获取父节点

node.parent

  

原文地址:https://www.cnblogs.com/liaoshiqi/p/10613970.html