精华内容
下载资源
问答
  • vue-tree-chart
    2021-02-18 14:52:27

    文档: https://github.com/tower1229/Vue-Tree-Chart

    npm i vue-tree-chart --save
    

    Usage

    <TreeChart :json="treeData" />
    

    in script:

    import TreeChart from "vue-tree-chart";
    
    export default {
    	components: {
        	TreeChart
    	},
    	data() {
    		return {
    			treeData: {
    				...
    			}
    		}
    	}
    

    treeData 中支持的属性

    - name[String] to display a node name
    - image_url[String] to display a node image
    - children[Array] node`s children
    - mate[Array] node`s mate
    - class[Array] node`s class
    - extend[Boolean] show/hide node`s children, default True
    
    {
        name: 'root',
        image_url: "https://static.refined-x.com/avat.jpg",
        class: ["rootNode"],
        children: [
          {
            name: 'children1',
            image_url: "https://static.refined-x.com/avat1.jpg"
          },
          {
            name: 'children2',
            image_url: "https://static.refined-x.com/avat2.jpg",
            mate: [{
              name: 'mate',
              image_url: "https://static.refined-x.com/avat3.jpg"
            }],
            children: [
              {
                name: 'grandchild',
                image_url: "https://static.refined-x.com/avat.jpg"
              },
              {
                name: 'grandchild2',
                image_url: "https://static.refined-x.com/avat1.jpg"
              },
              {
                name: 'grandchild3',
                image_url: "https://static.refined-x.com/avat2.jpg"
              }
            ]
          },
          {
            name: 'children3',
            image_url: "https://static.refined-x.com/avat.jpg"
          }
        ]
      }
    

    事件

    click-node(node)
    Click on the node triggered, receive the current node data as a parameter
    
    更多相关内容
  • |演示页面演示Gif使用技术...注册vue-tree组件import VueTree from '@ssthouse/vue-tree-chart'import Vue from 'vue'Vue . component ( 'vue-tree' , VueTree ) 3.使用组件3.1基本用法见代码< template> < div clas
  • Vue-Tree-Chart.zip

    2020-06-05 16:49:42
    Vue-Tree-Chart. vue树形图 可以搭建组织架构图.
  • vue-tree-chart

    千次阅读 2021-07-08 10:11:01
    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="{...

    在这里插入图片描述

    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简单的使用

    千次阅读 2022-04-25 13:50:47
    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

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

    插件安装:

    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>
    

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

    展开全文
  • 基于 vue-tree-chart,生成项目效果预览,包含鼠标右击事件; vue-tree-chart:https://github.com/tower1229/Vue-Tree-Chart 大家可以直接安装使用(具体事例可以查看官网) 但是个人建议最好是下载整个项目,封装成...

    基于 vue-tree-chart,生成项目效果预览,包含鼠标右击事件;
    在这里插入图片描述
    vue-tree-chart:https://github.com/tower1229/Vue-Tree-Chart

    大家可以直接安装使用(具体事例可以查看官网)

    但是个人建议最好是下载整个项目,封装成组件调用

    基于官网初始代码,封装组件:

    <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>
    
    展开全文
  • zm-tree-org介绍一个简易版组织架构图,组件依赖于vue-org-tree, 在此基础上将部分源代码进行优化修改。可鼠标拖动拖拽,以及鼠标滚轮缩放,并且支持拖动节点改变树结构。安装npm install zm-tree-org --save# or ...
  • vue——实现组织架构图(vue-org-tree)——技能提升

    千次阅读 热门讨论 2021-08-13 14:59:37
    在main.js中引入vue-org-tree插件 import Vue from 'vue' import Vue2OrgTree from 'vue-tree-color' Vue.use(Vue2OrgTree) 4.运行项目,此时报错了 报错信息:Syntax Error: TypeError: this.getOptions is not a ...
  • 箭头指向的名字要一样 从'vue'导入Vue 从 'vue-table-with-tree-grid'导入ZkTable Vue.component( ZkTable . name , ZkTable ) 可以解决
  • vue-tree树状图,横向树状图,流程图

    千次阅读 2020-08-26 15:28:45
    souce git:https://github.com/zhuyuhaoliar/vue-tree-right npm:https://www.npmjs.com/package/vue-tree-right ...1.import TreeRight from "vue-tree-right" 2.components: { TreeRight, } 3.list: [//datasource
  • vue-okr-tree 组件左右树结构

    千次阅读 热门讨论 2021-02-18 10:57:44
    最近公司需要做一个okr项目,okr项目里有一个对齐试图功能,在百度和GitHub上找了半天,最后终于找到了一位...大神的GitHub:https://github.com/qq449245884/vue-okr-tree 最终的展示效果如图: 子组件: <.
  • If you are using vue, see Installation # use npm npm i react-org-tree # use yarn yarn add react-org-tree Usage import OrgTree from 'react-org-tree'; const horizontal = false; // true:横向 false:纵向...
  • vue-org-tree 组织结构图组件应用及源码分析

    千次阅读 热门讨论 2019-09-05 09:58:57
    需求: 最近业务需要做类似思维导图的组织结构树功能,需要能动态增删改节点,且每层的节点样式并不相同 可用插件: 网上能找到的组织结构图插件有: ...2.vue-orgchart 地址:https://github.com/spiritre...
  • 基于最新的vue开发堆栈,它具有内置的i18n解决方案,企业应用程序的典型模板以及许多很棒的功能。 它可以帮助您构建大型而复杂的单页应用程序。 我相信无论您有什么需求,该项目都将为您提供帮助。 国内用户可访问...
  • 基于最新的vue开发堆栈,并且具有内置的i18n解决方案,企业应用程序的典型模板以及许多出色的功能。 它可以帮助您构建大型而复杂的单页应用程序。 我相信无论您有什么需求,该项目都将为您提供帮助。国内用户可访问...
  • vue-tree-chart 组织架构 树状图组件
  • :umbrella_on_ground: 线上预览vue3.x 版本预览(vue-next-admin)vue2.x 版本预览(vue-prev-admin):wedding: 代码仓库vue3.x 版本vue2.x 版本:construction: 安装 cnpm、yarn复制代码(桌面 cmd 运行) npm install...
  • vue-element-admin 精简版

    2022-03-03 14:52:16
    减少冗余组件,保留基本框架以及设置和头部栏。
  • #thinkphp6+vue2.6+element2.13 前后端分离落地解决方案 本人开发环境版本信息: npm=6.13.4 vue =@vue/cli 4.1.2 node=v12.14.1 #注意1:vue-admin 中接口请求规则和动态路由,是对应tp6 中的接口规则和权限规则,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,328
精华内容 931
关键字:

vue-tree-chart