vue组件横向树实现代码

实现一个 vue 组件横向树需要以下步骤:

第一步:安装依赖

横向树的实现需要使用到 d3 (Data-Driven Documents) 库,而在 Vue 中使用 d3 需要先安装依赖。可以通过 npm 来安装:

npm install d3@5.15.0

对于 Vue 项目,可以在 main.js 中引入 d3 库,以便在整个项目中使用:

import * as d3 from "d3";
Vue.prototype.$d3 = d3;

第二步:实现组件

实现横向树的核心代码是在组件中编写的。下面是一个示例:

<template>
  <div class="tree-diagram">
    <svg :width="width" :height="height">
      <g :transform="'translate(' + margin.left + ',' + margin.top + ')'">
        <template v-if="data">
          <rect class="background" :width="treeWidth" :height="treeHeight" @click.stop=""></rect>
          <g :transform="'translate(' + paddingLeft + ',' + paddingTop + ')'">
            <TreeNode
              :node="data"
              :level="1"
              :height="height"
              :width="width"
              :nodeWidth="nodeWidth"
              :nodeHeight="nodeHeight"
              :linkStrokeWidth="linkStrokeWidth"
              :linkStrokeColor="linkStrokeColor"
              :nodeFillColor="nodeFillColor"
              :nodeTextColor="nodeTextColor"
              @node-clicked="onNodeClicked"
            ></TreeNode>
          </g>
        </template>
        <template v-else>
          <text>No Data</text>
        </template>
      </g>
    </svg>
  </div>
</template>
<script>
import TreeNode from "./TreeNode.vue";

export default {
  name: "TreeDiagram",
  components: {
    TreeNode,
  },
  props: {
    data: {
      type: Object,
      default: null,
    },
    width: {
      type: Number,
      default: 800,
    },
    height: {
      type: Number,
      default: 600,
    },
    nodeWidth: {
      type: Number,
      default: 200,
    },
    nodeHeight: {
      type: Number,
      default: 80,
    },
    linkStrokeWidth: {
      type: Number,
      default: 4,
    },
    linkStrokeColor: {
      type: String,
      default: "#666",
    },
    nodeFillColor: {
      type: String,
      default: "#fff",
    },
    nodeTextColor: {
      type: String,
      default: "#000",
    },
  },
  data() {
    return {
      margin: {
        top: 20,
        right: 20,
        bottom: 20,
        left: 20,
      },
    };
  },
  computed: {
    treeWidth() {
      return this.nodeWidth * 2 + this.paddingLeft * 2;
    },
    treeHeight() {
      return this.nodeHeight * 2 + this.paddingTop * 2;
    },
    paddingLeft() {
      return this.nodeWidth * 0.5;
    },
    paddingTop() {
      return this.nodeHeight * 0.5;
    },
  },
  methods: {
    onNodeClicked(node) {
      this.$emit("node-clicked", node);
    },
  },
};
</script>
<style scoped>
.background {
  fill: none;
}

.node {
  font: 10px sans-serif;
  cursor: pointer;
}

.node circle {
  fill: #fff;
  stroke: steelblue;
  stroke-width: 1.5px;
}

.link {
  fill: none;
  stroke: #ccc;
  stroke-width: 2px;
}
</style>

上面的代码中使用到了 TreeNode 组件,可以通过下面的代码来实现:

<template>
  <g :transform="'translate(' + (node.x - nodeWidth / 2) + ',' + (node.y - nodeHeight / 2) + ')'">
    <rect :width="nodeWidth" :height="nodeHeight" :fill="nodeFillColor"></rect>
    <text :x="nodeWidth / 2" :y="nodeHeight / 2" :dy="nodeHeight * 0.35" :text-anchor="'middle'" :fill="nodeTextColor">
      {{ node.name }}
    </text>
    <template v-if="node.children">
      <g class="children">
        <template v-for="(child, index) in node.children" :key="index">
          <TreeNode
            :node="child"
            :level="(level || 0) + 1"
            :height="height"
            :width="width"
            :nodeWidth="nodeWidth"
            :nodeHeight="nodeHeight"
            :linkStrokeWidth="linkStrokeWidth"
            :linkStrokeColor="linkStrokeColor"
            :nodeFillColor="nodeFillColor"
            :nodeTextColor="nodeTextColor"
            @node-clicked="onNodeClicked"
          ></TreeNode>
        </template>
      </g>
    </template>
  </g>
</template>
<script>
export default {
  name: "TreeNode",
  props: {
    node: {
      type: Object,
      default: null,
      required: true,
    },
    level: {
      type: Number,
      default: null,
    },
    height: {
      type: Number,
      default: 600,
    },
    width: {
      type: Number,
      default: 800,
    },
    nodeWidth: {
      type: Number,
      default: 200,
    },
    nodeHeight: {
      type: Number,
      default: 80,
    },
    linkStrokeWidth: {
      type: Number,
      default: 4,
    },
    linkStrokeColor: {
      type: String,
      default: "#666",
    },
    nodeFillColor: {
      type: String,
      default: "#fff",
    },
    nodeTextColor: {
      type: String,
      default: "#000",
    },
  },
  computed: {
    isRoot() {
      return this.level === 1;
    },
  },
  methods: {
    onNodeClicked() {
      this.$emit("node-clicked", this.node);
    },
  },
};
</script>
<style scoped>
</style>

示例说明

下面是两个示例:

  1. 显示简单数据结构的横向树
<template>
  <TreeDiagram :data="treeData" @node-clicked="onNodeClicked" />
</template>
<script>
import TreeDiagram from "./TreeDiagram.vue";

export default {
  name: "App",
  components: {
    TreeDiagram,
  },
  data() {
    const treeData = {
      name: "rootNode",
      children: [
        {
          name: "childNode1",
        },
        {
          name: "childNode2",
        },
      ],
    };

    return {
      treeData,
    };
  },
  methods: {
    onNodeClicked(node) {
      console.log("Node Clicked: ", node);
    },
  },
};
</script>
  1. 显示复杂数据结构的横向树
<template>
  <TreeDiagram :data="treeData" />
</template>
<script>
import TreeDiagram from "./TreeDiagram.vue";

const data = {
  name: "flare",
  children: [
    {
      name: "data",
      children: [
        {
          name: "converters",
          children: [
            { name: "Converters", value: 721 },
            { name: "DelimitedTextConverter", value: 4294 },
          ],
        },
      ],
    },
    {
      name: "display",
      children: [
        { name: "DirtySprite", value: 8833 },
        {
          name: "LineSprite",
          children: [
            { name: "Arrows", value: 841 },
            { name: "LineSprite", value: 1769 },
          ],
        },
      ],
    },
  ],
};

export default {
  name: "App",
  components: {
    TreeDiagram,
  },
  data() {
    return {
      treeData: data,
    };
  },
};
</script>

参考文献:

  1. vue 组件横向树实现 https://www.jianshu.com/p/694a99d50de3
  2. D3.js https://d3js.org/

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:vue组件横向树实现代码 - Python技术站

(0)
上一篇 2023年5月27日
下一篇 2023年5月27日

相关文章

  • Springboot Vue可配置调度任务实现示例详解

    下面我将为您详细讲解“Springboot Vue可配置调度任务实现示例详解”的完整攻略。 简介 本攻略将介绍如何使用Springboot和Vue实现可配置调度任务,主要涵盖以下内容: 何为可配置调度任务 实现可配置调度任务的技术选型 实现步骤和示例说明 什么是可配置调度任务 可配置调度任务是指可以根据用户需求动态添加、修改、删除的定时任务,而不需要每次都手…

    Vue 2023年5月28日
    00
  • springboot vue接口测试前端动态增删表单功能实现

    下面是关于“springboot vue接口测试前端动态增删表单功能实现”的完整攻略: 一、概述 这篇攻略介绍了如何使用Spring Boot和Vue.js构建一个带有动态增删表单功能的前端页面,并且可以通过接口测试实现数据的增删查改等操作。 二、环境搭建 为了正确地使用Spring Boot和Vue.js开发本示例,我们需要安装以下环境: Java Dev…

    Vue 2023年5月28日
    00
  • websocket在springboot+vue中的使用教程

    下面是关于使用WebSocket在Spring Boot和Vue中的完整攻略。 WebSocket 在 Spring Boot 和 Vue 中的使用教程 什么是 WebSocket? WebSocket 是 HTML5 提供的一种在单个 TCP 连接上进行全双工通讯的协议。WebSocket 使得客户端和服务器之间的数据交换变得更加简单、更便捷,且可以实现低…

    Vue 2023年5月28日
    00
  • 谈谈对Vue Router的理解

    当我们构建单页应用程序(SPA)时,我们通常需要跟不同URL之间进行交互。这通常是通过前端路由来实现的,可以为不同的URL路径定义不同的视图层,使用户可以无感知地在不同的视图层之间进行切换。 Vue Router是一个官方的Vue.js路由管理器,它通过将组件映射到不同的路由来负责为应用程序提供前端路由,并且非常适合用于构建单页应用程序。接下来让我们来讨论一…

    Vue 2023年5月28日
    00
  • Vue中的局部组件介绍

    当我们在开发Vue应用程序时,我们通常需要将页面简化成多个模块化的组件。这个时候,我们可以使用Vue的局部组件来实现这个目的。Vue的局部组件是一种允许我们在单个Vue组件中注册私有的子组件的机制。在这个过程中,我们可以将一个Vue组件分解成多个小组件,并将这些组件放置在同一个父组件中,以更好地管理和重复使用这些组件。 如何在Vue中实现局部组件 在Vue中…

    Vue 2023年5月27日
    00
  • js中什么时候不能使用箭头函数

    使用箭头函数的时候需要注意一些使用限制,下面详细讲解什么时候不能使用箭头函数以及注意事项。 不能使用箭头函数的情况 1. 不能作为构造函数 箭头函数不能作为构造函数,也就是不能使用 new 关键字创建对象。因为箭头函数没有自己的 this,也没有 prototype 属性。所以,如果你尝试使用 “箭头函数” 作为构造函数,则会产生异常。 // 箭头函数不能作…

    Vue 2023年5月28日
    00
  • vue3 使用setup语法糖实现分类管理功能

    让我来详细讲解一下“vue3 使用setup语法糖实现分类管理功能”的完整攻略。 1. 环境准备 首先,我们需要完成一些准备工作: 安装最新版本的Vue CLI命令行工具 配置VSCode的插件Vetur,以获得更好的vue代码编辑体验 创建一个新的vue3项目。 2. 配置路由 在Vue项目中,我们需要先配置路由,才能实现不同页面之间的跳转。我们使用Vue…

    Vue 2023年5月27日
    00
  • 使用vue实现grid-layout功能实例代码

    使用Vue实现Grid-Layout功能需要使用vue-grid-layout插件,并结合Vue的生命周期进行使用。整个实现过程可分为以下几步: 安装vue-grid-layout插件。 首先需要在项目中安装vue-grid-layout插件,使用命令:npm install vue-grid-layout –save 进行安装。 在vue组件中引入并配置…

    Vue 2023年5月29日
    00
合作推广
合作推广
分享本页
返回顶部