vue3使用vue3-tree-org实现组织结构图

vue yekong

数据可视化大屏项目开发中,需要实现一个公司结构图效果,效果截图如下:

vue3使用vue3-tree-org实现组织结构图

这里我们使用的是vue3开发的,所以使用的插件是vue3-tree-org

插件版本

"vue3-tree-org": "^4.2.2",

vue3-tree-org

Vue3 Tree Org 是一个基于 Vue 3.x 的插件库,专门用于创建和管理组织结构树。它提供了一种高效且灵活的方式来展示树形数据,具有良好的可维护性和扩展性。以下是该插件的一些主要功能和特点:

  • 拖拽功能:支持通过拖拽节点来改变树结构。
  • 缩放功能:支持通过鼠标滚轮进行缩放操作。
  • 节点管理:支持新增和删除节点,以及编辑节点名称。
  • 自定义右键菜单:允许用户自定义右键菜单,以便执行特定操作。
  • Slot自定义节点:支持使用 slot 来自定义节点的渲染内容,提供更大的灵活性。

安装依赖

pnpm i vue3-tree-org

main.js引入

import vue3TreeOrg from 'vue3-tree-org';
import "vue3-tree-org/lib/vue3-tree-org.css";
use(vue3TreeOrg)

实例代码

<template>
  <div class="treeBody">
    <vue3-tree-org
        :data="data"
        center
        :horizontal="horizontal"
        :collapsable="collapsable"
        :label-style="style"
        :only-one-node="onlyOneNode"
        :clone-node-drag="cloneNodeDrag"
        :before-drag-end="beforeDragEnd"
        :node-draggable="false"
        @on-node-drag="nodeDragMove"
        @on-node-drag-end="nodeDragEnd"
        @on-contextmenu="onMenus"
        @on-expand="onExpand"
    />
  </div>
</template>

<script>
import {ref} from 'vue'

export default {
  name: "baseTree",
  components: {
  },
  setup() {
    const cloneNodeDrag = ref(false)
    return {
      cloneNodeDrag
    }
  },
  data() {
    return {
      data: {
        "id": 1, "label": "公司董事会",
        "children": [
          {
            "id": 2, "pid": 1, "label": "科学技术委员会",
            "children": [
              {
                "id": 5, "pid": 2, "label": "产品研发中心",
                "children": [
                  {"id": 9, "pid": 5, "label": "产品研发中心1"},
                  {"id": 10, "pid": 5, "label": "产品研发中心2"},
                  {"id": 11, "pid": 5, "label": "产品研发中心3"}
                ]
              },
              {
                "id": 6, "pid": 2, "label": "客户服务中心",
                "children": [
                  {"id": 12, "pid": 6, "label": "产品研发中心1"},
                  {"id": 13, "pid": 6, "label": "产品研发中心2"},
                  {"id": 14, "pid": 6, "label": "产品研发中心3"}
                ]
              },
              {
                "id": 7, "pid": 2, "label": "数据运营中心",
                "children": [
                  {"id": 15, "pid": 7, "label": "产品研发中心1"},
                  {"id": 16, "pid": 7, "label": "产品研发中心2"},
                  {"id": 17, "pid": 7, "label": "产品研发中心3"}
                ]
              },
              {
                "id": 8, "pid": 2, "label": "市场营销中心",
                "children": [
                  {"id": 18, "pid": 8, "label": "产品研发中心1"},
                  {"id": 19, "pid": 8, "label": "产品研发中心2"},
                  {"id": 20, "pid": 8, "label": "产品研发中心3"}
                ]
              }
            ]
          },
          {
            "id": 3, "pid": 1, "label": "专家委员会",
            "children": [
              {
                "id": 21, "pid": 3, "label": "产品研发中心",
                "children": [
                  {"id": 25, "pid": 21, "label": "产品研发中心1"},
                  {"id": 26, "pid": 21, "label": "产品研发中心2"},
                  {"id": 27, "pid": 21, "label": "产品研发中心3"}
                ]
              },
              {
                "id": 22, "pid": 3, "label": "客户服务中心",
                "children": [
                  {"id": 28, "pid": 22, "label": "产品研发中心1"},
                  {"id": 29, "pid": 22, "label": "产品研发中心2"},
                  {"id": 30, "pid": 22, "label": "产品研发中心3"}
                ]
              },
              {
                "id": 23, "pid": 3, "label": "数据运营中心",
                "children": [
                  {"id": 31, "pid": 23, "label": "产品研发中心1"},
                  {"id": 32, "pid": 23, "label": "产品研发中心2"},
                  {"id": 33, "pid": 23, "label": "产品研发中心3"}
                ]
              },
              {
                "id": 24, "pid": 3, "label": "市场营销中心",
                "children": [
                  {"id": 34, "pid": 24, "label": "产品研发中心1"},
                  {"id": 35, "pid": 24, "label": "产品研发中心2"},
                  {"id": 36, "pid": 24, "label": "产品研发中心3"}
                ]
              }
            ]
          }
        ]
      },
      horizontal: false,
      collapsable: false,
      onlyOneNode: false,
      expandAll: true,
      disaled: true,
      style: {
        background: "rgba(41, 86, 131, 1)",
        color: "#FFFFFF",
        fontFamily: "MicrosoftYaHei",
        fontWeight: 400,
        fontSize: "14px",
      },
    };
  },
  methods: {
    onMenus(event, data) {
      event.preventDefault(); // 阻止默认右键菜单行为
      event.stopPropagation(); // 阻止事件冒泡
      console.log('右键菜单已被禁用', data);
    },
    onExpand(e, data) {
      console.log(e, data);
    },
    nodeDragMove(data) {
      console.log(data);
    },
    beforeDragEnd(node, targetNode) {
      return new Promise((resolve, reject) => {
        if (!targetNode) reject()
        if (node.id === targetNode.id) {
          reject()
        } else {
          resolve()
        }
      })
    },
    nodeDragEnd(data, isSelf) {
      console.log(data, isSelf);
    },
    toggleExpand(data, val) {
      if (Array.isArray(data)) {
        data.forEach((item) => {
          item.expand = val
          if (item.children) {
            this.toggleExpand(item.children, val);
          }
        });
      } else {
        data.expand = val
        if (data.children) {
          this.toggleExpand(data.children, val);
        }
      }
    },
  },
};
</script>

<style lang="scss">
.zm-tree-org {
  background: none !important;
}

.treeBody {
  position: relative;
  width: 100%;
  height: 100%;
}

.vue3-tree-org {
  .tree-node {
    .label-wrapper {
      .label {
        font-family: MicrosoftYaHei;
        font-weight: 400;
        font-size: 14px;
        color: #FFFFFF;
        background-color: rgba(41, 86, 131, 1);
      }
    }
  }

  // 添加以下样式来更改连接线颜色
  .lines {
    .line {
      stroke: rgba(41, 48, 72, 1) !important;
    }
  }
}

.zm-tree-contextmenu {
  display: none !important;
}

.zm-tree-handle {
  display: none !important;
}
</style>

演示地址

vue3使用vue3-tree-org实现组织结构图

喜欢