npm i vue-tree-chart --save

组件

<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 : []"><div class="avat"><img :src="treeData.image_url" @contextmenu="$emit('click-node', treeData)"/></div><!-- <div class="name">{{treeData.name}}</div> --></div><div class="paeson_name">{{treeData.name}}</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><div class="paeson_name">{{treeData.name}}</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 50px 0;text-align: center; }
.extend_handle{position: absolute;left:50%;bottom:30px; width:10px;height: 10px;padding:10px;transform: translate3d(-15px,0,0);cursor: pointer;}
.extend_handle:before{content:""; display: block; width:100%;height: 100%;box-sizing: border-box; border:2px solid;border-color:#ccc #ccc transparent transparent;
transform: rotateZ(135deg);transform-origin: 50% 50% 0;transition: transform ease 300ms;}
.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:15px;border-left:2px solid #ccc;transform: translate3d(-1px,0,0)}
.childLevel::before{content: "";position: absolute;left:50%;bottom:100%;height:15px;border-left:2px solid #ccc;transform: translate3d(-1px,0,0)}
.childLevel::after{content: "";position: absolute;left:0;right:0;top:-15px;border-top:2px solid #ccc;}
.childLevel:first-child:before, .childLevel:last-child:before{display: none;}
.childLevel:first-child:after{left:50%;height:15px; border:2px solid;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 solid;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:hover{color: #2d8cf0;cursor: pointer;}
.node .person{position: relative; display: inline-block;z-index: 2;width:6em; overflow: hidden;}
.node .person .avat{display: block;width:4em;height: 4em;margin:auto;overflow:hidden; background:#fff;border:1px solid #ccc;box-sizing: border-box;}
.node .person .avat:hover{ border: 1px solid #2d8cf0;}
.node .person .avat img{width:100%;height: 100%;}
.node .person .name{height:2em;line-height: 2em;overflow: hidden;width:100%;}
.node.hasMate::after{content: "";position: absolute;left:2em;right:2em;top:2em;border-top:2px solid #ccc;z-index: 1;}
.node .paeson_name{transform: rotate(90deg);position: absolute; top: 68px;right: 39px;width: 88px;text-align: center;text-overflow: ellipsis; overflow: hidden; white-space: nowrap;}.landscape{transform:translate(-100%,0) rotate(-90deg);transform-origin: 100% 0;}
.landscape .node{text-align: left;height: 8em;width:8em;right: 18px;}
.landscape .person{position: absolute; transform: rotate(90deg);height: 4em;top:4em;left: 2.5em;}
.landscape .person .avat{position: absolute;left: 0;border-radius: 2em;border-width:2px;}
.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>

调用组件

<template><div id="app"><TreeChart :json="data" :class="{landscape: 1}" @click-node="clickNode" /><div class="gl_prs_ctn" :style='[contextstyle]'><ul class='gl_prs_li'><li >添加</li><li >详情</li><li >编辑</li><li >删除</li></ul></div>  </div>
</template><script>
import TreeChart from "./treechar";
export default {name: 'app',components: {TreeChart},data() {return {data: {name: 'root',image_url: "https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3689173839,956040439&fm=26&gp=0.jpg",class: ["rootNode"],children: [{name: 'children1',image_url: "https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3689173839,956040439&fm=26&gp=0.jpg"},{name: 'children2',image_url: "https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3689173839,956040439&fm=26&gp=0.jpg",children: [{name: 'grandchild',image_url: "https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3689173839,956040439&fm=26&gp=0.jpg"},{name: 'grandchild2',image_url: "https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3689173839,956040439&fm=26&gp=0.jpg"},{name: 'grandchild3',image_url: "https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3689173839,956040439&fm=26&gp=0.jpg"}]}]},contextstyle: {display: 'none',right: '0px',top: '0px',left: '0px',bottom: '0px',}, }},created(){document.oncontextmenu = ()=>{return false}document.addEventListener("click", (event) => {if(this.contextstyle.display == 'block'){this.contextstyle.display = 'none'}})},methods: {clickNode(node){if(window.event.x + 188 > document.documentElement.clientWidth){this.contextstyle.left = 'unset';this.contextstyle.right = document.documentElement.clientWidth - window.event.x + 'px';}else{this.contextstyle.left = window.event.x + 'px';}if(window.event.y + 166 > document.documentElement.clientHeight){this.contextstyle.top = 'unset';this.contextstyle.bottom = document.documentElement.clientHeight - window.event.y + 'px';}else{this.contextstyle.top = window.event.y + 'px';}                       this.contextstyle.display = 'block';},}
}
</script><style>
#app {font-family: 'Avenir', Helvetica, Arial, sans-serif;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;text-align: center;color: #2c3e50;margin-top: 60px;
}
.gl_prs_ctn{width: 188px;background: rgb(255, 255, 255);box-shadow: rgba(0, 0, 0, 0.075) 0px 1px 1px inset, rgba(102, 175, 233, 0.6) 0px 0px 8px;z-index: 99999;position: fixed;padding: 10px;box-sizing: content-box;height: 142px;
}
.gl_prs_li{padding: unset;margin: unset;}
.gl_prs_li>li{cursor: pointer;   list-style: none;border-bottom: 1px solid #efefef;padding: 7px 10px;
}
li:last-child { border: unset }
li:hover{background: #ccc;color: #fff;
}
</style>

vue-tree-chart相关推荐

  1. Vue——vue-chartjs[Vue 对于 Chart.js 的封装]

    基本概念 vue-chartjs:vue-chartjs is a wrapper for Chart.js in vue. You can easily create reuseable chart ...

  2. vue tree组件_Ant-Design-Vue和Icon按需加载方案 - JeecgBoot实战

    JeecgBoot实战 - 按需加载方案 一.Ant-Design-Vue 按需加载 1.创建js文件 src/components/lazy_antd.js import Vue from 'vue ...

  3. vue tree组件_使用Vue 3.0做JSX(TSX)风格的组件开发

    前言 我日常工作都是使用React来做开发,但是我对React一直不是很满意,特别是在推出React Hooks以后. 不可否认React Hooks极大地方便了开发者,但是它又有非常多反直觉的地方, ...

  4. vue tree组件_基于 Vue2.0 和 HeyUI 组件库的中后端系统 HeyUI Admin

    介绍 heyui-admin 是一个成熟的企业应用解决方案,基于 vue2.0 和 heyui 组件库的中后端系统. 功能 - Js - common / 通用 - ajax / 封装axios - ...

  5. 关于Antdesign vue tree组件开发中遇到的问题

    1.设置了:loadData 属性后,树节点在展开下级节点时,loading一直在. 解决办法 loadData() {return new Promise((resolve) => {// 重 ...

  6. 前端开发之vue可视化数据图表组件(Chart.js)

    前端开发之vue可视化数据图表组件(Chart.js) 前言 制作好的效果图 vue2中使用Chart.js 1.在项目中安装Chart.js 组件 2.vue文件 vue3中使用Chart.js v ...

  7. js文件里获取路由 vue_「如何优雅的使用Vue?」不可不知的Vue实战技巧

    作者: CHICAGO 转发连接:https://juejin.im/post/5e475829f265da57444ab10f 前言 在大家都会用vue的时代,我们又如何去区别是新手小白还是资深vu ...

  8. Vue 面试题 (全)

    vue用的什么web模板引擎? jade模板,后来由于商标原因改成了pug v-model的原理? 数据双向绑定的指令,同步控件输入值到data属性 更新data绑定属性,更新控件的值. view层和 ...

  9. vue 时间插件_Vue3 插件开发详解尝鲜版「值得收藏」

    作者:lishuai 转发链接:https://segmentfault.com/a/1190000022757326 前言 vue3.0-beta 版本已经发布了一段时间了,正式版本据说在年中发布( ...

  10. animation基础练习源码_用vue简单写一个音乐播放组件「附源码」

    作者:vipbic 转发链接:https://segmentfault.com/a/1190000022980992 前言 上次小编也分享一个关于Vue 开发过音乐播放对项目: 基于 electron ...

最新文章

  1. 扩展gcd codevs 1200 同余方程
  2. python元组支持双向索引吗_2、Python列表和元组
  3. Python之PIL库的运用、GIF处理
  4. 协调器太多,cc2530的终端或则路由器选择性加入协调器的方法
  5. 8个你应该了解的正则表达式
  6. The 2020 ICPC Asia Macau Regional Contest A. Accelerator(分治+NTT)
  7. 为什么awt_为AWT的机器人创建DSL
  8. 前端学习(1895)vue之电商管理系统电商系统之组件的分页显示
  9. python取的键不存在_Python3基础 dict get 在查询不存在的键时,返回指定的内容
  10. mysql数据库(9):常用查询的例子
  11. PyQt5 GUI Programming With Python 3.6 (一)
  12. scrapy tool 命令
  13. 垃圾回收机制,垃圾回收的几种方法以及
  14. 3796.凑平方-AcWing题库
  15. treeview的checkbox展开节点
  16. win10易升_电脑win7系统免费自动升级至win10系统,获得持续软件和安全更新
  17. GBASE 8s DB-Access入门
  18. Extreme DAX中文第1章 商业智能中的DAX
  19. uni-app安卓禁止截屏,一行代码
  20. android textview基线,关于Textview基准线的计算

热门文章

  1. GitHub上不错的Android开源项目(三)
  2. 程序设计基础(计算机类2014) 实验4 选择控制结构1
  3. jQuery获取和计算对象(object)的长度
  4. Unity 用于投掷物品的一阶贝塞尔曲线
  5. 交通标志的检测与识别
  6. 《野兽绅士》总结3——出手抓她的时候“用力一点”
  7. 软件测试团队收获,软件测试中如何团队合作才能和谐?
  8. 手机网站常用的推广方式有哪些
  9. 如何使用Inkscape软件绘制一个LOGO
  10. 想要空手夺白刃?看看用户裂变的四板斧