IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> vue-tree-chart简单的使用 -> 正文阅读

[JavaScript知识库]vue-tree-chart简单的使用

项目中需要动态展示组织结构,这里只是展示简单的实现,如果需要更复杂的就需要去深入去实现。

插件安装:

npm i vue-tree-chart --save

组件内容:vart.vue

<template>
    <table v-if="treeData.name">
      <tr>
        <td :colspan="Array.isArray(treeData.children) ? treeData.children.length * 2 : 1" 
          :class="{parentLevel: Array.isArray(treeData.children) && treeData.children.length, 
          extend: Array.isArray(treeData.children) && treeData.children.length && treeData.extend}">
          <div :class="{node: true, hasMate: treeData.mate}">
            <div class="person"  :class="Array.isArray(treeData.class) ? treeData.class : []"
              @click="$emit('click-node', treeData)">
              <div class="avat">
                <img :src="treeData.image_url" />
              </div>
              <div class="right">
                <div class="name1">META PRINCIPAL</div>
                <div class="name">{{treeData.name}}</div>
                <div class="name2">{{treeData.n}}</div>
              </div>
            </div>
            <template v-if="Array.isArray(treeData.mate) && treeData.mate.length">
              <!-- <div class="person" v-for="(mate, mateIndex) in treeData.mate" :key="treeData.name+mateIndex"
                :class="Array.isArray(mate.class) ? mate.class : []"
                @click="$emit('click-node', mate)" >
                <div class="avat">
                  <img :src="mate.image_url" />
                </div>
                <div class="name">{{mate.name}}</div>
              </div> -->
            </template>
          </div>
          <div class="extend_handle" v-if="Array.isArray(treeData.children) && treeData.children.length" @click="toggleExtend(treeData)"></div>
        </td>
      </tr>
      <!-- 这是一个递归组件,注意,这里还要调用,需要传递的数据这里也要传递,否则操作时拿不到子级的数据 -->
      <tr v-if="Array.isArray(treeData.children) && treeData.children.length && treeData.extend">
        <td v-for="(children, index) in treeData.children" :key="index" colspan="2" class="childLevel">
          <TreeChart :json="children" @click-node="$emit('click-node', $event)"/>
        </td>
      </tr>
    </table>
</template>

<script>
export default {
  name: "TreeChart",
  props: ["json"],
  data() {
    return {
      treeData: {}
    }
  },
  watch: {
    // 遍历当前的数据
    json: {
      handler: function(Props){
        let extendKey = function(jsonData){
          jsonData.extend = (jsonData.extend===void 0 ? true: !!jsonData.extend);
          if(Array.isArray(jsonData.children)){
            jsonData.children.forEach(c => {
              extendKey(c)
            })
          }
          return jsonData;
        }
        if(Props){
          this.treeData = extendKey(Props);
        }
      },
      immediate: true
    }
  },
  methods: {
    toggleExtend: function(treeData){
      treeData.extend = !treeData.extend;
      this.$forceUpdate();
    }
  }
}
</script>

<style scoped>
table{
  border-collapse: separate!important;
  border-spacing: 0!important;
  }
td{
  position: relative; 
  vertical-align: top;
  padding:0 0 40px 0;
  text-align: center; 
}
.extend_handle:hover:before{
  border-color:#333 #333 transparent transparent;
  }
.extend .extend_handle:before{
  transform: rotateZ(-45deg);
  }
.extend::after{
  content: "";
  position: absolute;
  left:50%;
  bottom:15px;
  height:20px;
  border-left:2px dashed #ccc;
  transform: translate3d(-1px,0,0)
  }
.childLevel::before{
  content: "";
  position: absolute;
  left:50%
  ;bottom:100%;
  height:15px;
  border-left:2px dashed  #ccc;
  transform: translate3d(-1px,0,0)}
.childLevel::after{
  content: "";
  position: absolute;
  left:0;
  right:0;
  top:-15px;
  border-top:2px dashed #ccc;
  }
.childLevel:first-child:before, .childLevel:last-child:before{
  display: none;
}
.childLevel:first-child:after{
  left:50%;height:15px;
   border:2px dashed;
   border-color:#ccc transparent transparent #ccc;
   border-radius: 6px 0 0 0;transform: translate3d(1px,0,0);
}
.childLevel:last-child:after{
  right:50%;
  height:15px; 
  border:2px dashed;
  border-color:#ccc #ccc transparent transparent;
  border-radius: 0 6px 0 0;
  transform: translate3d(-1px,0,0);
}
.childLevel:first-child.childLevel:last-child::after{
  left:auto;
  border-radius: 0;
  border-color:transparent #ccc transparent transparent;
  transform: translate3d(1px,0,0)
}
.node{
  position: relative;
   display: inline-block;
   margin: 0 1em;
   box-sizing: border-box; 
  text-align: center;
}
.node .person{
  position: relative;
  display: inline-block;
  z-index: 2;
  width:16em;
  height: 8em;
  overflow: hidden;
  border-radius: 4px;
  display: flex;
  padding:17px 0px 20px 10px;
}
.node .person:nth-child(1){
  border:1px solid #409EFF;
  background: #409EFF;
}
.node .person .avat{
  display: block;
  width:4em;
  height: 60px;
  overflow:hidden; 
  background:#fff;
  border-radius: 8px;
  border:1px solid #ccc;
  box-sizing: border-box;
}
.right{
  text-align: left;
  padding-left: 10px;
  color: #fff;
}
.name1{
  font-weight:bold;
}
.name{
  border-bottom: 1px solid #ffffff;

}
.name2{
  padding-top:8px;
}
.node .person .avat img{
  width:100%;
  height: 60px;
}
.node .person .name{
  height:2em;
  line-height: 2em;
  overflow: hidden;
  color: #fff;
  width:100%;
}
.node.hasMate::after{
  content: "";
  position: absolute;
  left:2em;
  right:2em;
  top:2em;
  border-top:2px solid #ccc;
  z-index: 1;
}
/* 横板 */
.landscape{
  transform:translate(-100%,0) rotate(-90deg);
  transform-origin: 100% 0;
}
.landscape .node{
  text-align: left;
  height: 8em;
  width:8em;
}
.landscape .person{
  position: relative;
   transform: rotate(90deg);
   padding-left: 4.5em;
   height: 4em;
   top:4em;
   left: -1em;
  }
.landscape .person .avat{
  position: absolute;
  left: 0;
}
.landscape .person .name{
  height: 4em;
   line-height: 4em;
}
.landscape .hasMate{
  position: relative;
}
.landscape .hasMate .person{
  position: absolute; 
}
.landscape .hasMate .person:first-child{
  left:auto; 
  right:-4em;
}
.landscape .hasMate .person:last-child{
  left: -4em;
  margin-left:0;
}
</style>

页面中使用:

 <div class="app" style="height:560px;width:100%;position:relative;margin-left:20%;">
        <TreeChart :json="dataList" :class="{landscape: landscape.length}" @click-node="clickNode" />
      </div>

<script>
import TreeChart from "./vart";
export default {
  components: {TreeChart},
  data() {
    return {
      dataList: {
        name: '何xx',
        n:'xxxx',
        image_url: "https://static.refined-x.com/static/avatar.jpg",
        class: ["rootNode"],
        children: [
         {
            name: '张xxx',
            n:'xxxx',
            image_url: "https://static.refined-x.com/static/avatar.jpg",
            children:[
              {
                name: '代x',
                n:'xxx',
                image_url: "https://static.refined-x.com/static/avatar.jpg",
                 children: [
                  {
                    name: '李x', n:'xxx',
                    image_url: "https://static.refined-x.com/static/avatar.jpg"
                  },
                  {
                    name: '李x', n:'xxx,
                    image_url: "https://static.refined-x.com/static/avatar.jpg"
                  },
                  {
                    name: '赵x', n:'xxxx',
                    image_url: "https://static.refined-x.com/static/avatar.jpg"
                  }
                ]
              },
            ]
          },
        ]
      },
    }
  },
  methods: {
    clickNode: function(node){
      console.log(node)
    },
  }
}
</script>
<style lang="scss" scoped>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}
#app .avat{
  border-radius: 2em;
  border-width:2px;
}
#app .name{
  font-weight:700;
}
#app .rootNode .name{
  color: red;
}
</style>

最后展示简单结构图
在这里插入图片描述

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-04-26 11:33:45  更:2022-04-26 11:35:33 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 1:33:53-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码