zoukankan      html  css  js  c++  java
  • 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
    

      

  • 相关阅读:
    ZEIT – Next.js
    Segment Open
    Segment Open
    analytics.js
    Web scraping with Nightmare.js | azurelogic.com
    技能树升级——Chrome Headless模式
    simple-headless-chrome
    simple-headless-chrome
    cyrus-and/chrome-remote-interface: Chrome Debugging Protocol interface for Node.js
    python
  • 原文地址:https://www.cnblogs.com/liaoshiqi/p/10613970.html
Copyright © 2011-2022 走看看