• 横向结构的树组件(leader-line-vue)


    近期做项目时需要做一个横向的树结构的图,如下所示:

     本图的实现采用了leader-line-vue组件,

    具体实现如下:

    先npm install leader-line-vue --save,安装依赖

    然后,子组件RightTree的封装,代码如下:

      1 <template>
      2   <div class="TreeRight" id="treeRight" v-if="showTree">
      3     <div class="childs">
      4       <div
      5         class="child"
      6         v-for="(item, index) in list"
      7         :key="item.id + '-child-' + index"
      8       >
      9         <div
     10           class="child-item"
     11           :style="{
     12             marginRight:
     13               item.children && item.children.length > 1 ? '20px' : '',
     14           }"
     15         >
     16           <div class="childname" :id="item">
     17             <div class="content-box" :ref="item.id" :id="item.id">
     18               {{ item.id }}
     19               <p
     20                 v-for="(itemshow, index3) in showfields"
     21                 :key="'itemshow' + index3"
     22               >
     23                 {{ itemshow.name }}{{ item[itemshow.key] }}
     24               </p>
     25             </div>
     26             <div style=" 30px"></div>
     27             <div
     28               class="position-top"
     29               v-if="isFirst(item.id) && domready"
     30               :style="position_top(item.id, 'top')"
     31             ></div>
     32             <div
     33               class="position-top"
     34               v-if="isLast(item.id)"
     35               :style="position_top(item.id, 'bottom')"
     36             ></div>
     37           </div>
     38           <div style=" 160px"></div>
     39         </div>
     40         <!-- 递归组件展示子节点 -->
     41         <div
     42           class="child-children"
     43           v-if="item.children && item.children.length"
     44         >
     45           <RightTree :list="item.children" :showfields="showfields" />
     46         </div>
     47       </div>
     48     </div>
     49   </div>
     50 </template>
     51 
     52 <script>
     53 import LeaderLine from "leader-line-vue";
     54 export default {
     55   name: "RightTree",
     56   components: {},
     57   data() {
     58     return {
     59       domready: false,
     60       lines: [],
     61     };
     62   },
     63   created() {},
     64   props: {
     65     list: {
     66       type: Array,
     67       default: () => [],
     68     },
     69     showfields: {
     70       type: Array,
     71       default: () => [],
     72     },
     73   },
     74   mounted() {
     75     this.$nextTick(() => {
     76       this.domready = true;
     77       this.drawArrowLine();
     78     });
     79   },
     80   computed: {
     81     /**
     82      * 是否展示树计算属性
     83      */
     84     showTree() {
     85       return this.list && this.list.length;
     86     },
     87   },
     88   beforeDestroy() {
     89     /**
     90      * 离开页面时销毁所有line
     91      */
     92     if (this.lines && this.lines.length) {
     93       this.lines.forEach((line) => {
     94         line.remove();
     95       });
     96     }
     97   },
     98   methods: {
     99     /**
    100      * 递归绘制箭头
    101      */
    102     drawArrowLine() {
    103       this.drawLeaderLine(this.list);
    104       document.getElementById("treeRight").addEventListener("scroll", () => {
    105       if (this.lines && this.lines.length) {
    106         this.lines.forEach((line) => {
    107           line.position();
    108         });
    109       }
    110     });
    111     },
    112     /**
    113      * 根据上下级关系绘制线条
    114      */
    115     drawLeaderLine(list) {
    116       list.forEach((element) => {
    117         let start = document.getElementById(element.id);
    118         if (element.children && element.children.length) {
    119           element.children.forEach((child) => {
    120             let line = LeaderLine.setLine(
    121               start,
    122               document.getElementById(child.id)
    123             );
    124             line.color = "#7F7F7F";
    125             line.path = "fluid";
    126             line.size = 1;
    127             line.setOptions({
    128               solid: { animation: true },
    129             });
    130             this.lines.push(line);
    131           });
    132           this.drawLeaderLine(element.children);
    133         }
    134       });
    135     },
    136     position_top(id, position) {
    137       let dom = document.getElementById(id);
    138       let height;
    139       if (dom) {
    140         height = dom.clientHeight;
    141       }
    142       let rt;
    143       if (position === "top") {
    144         rt = {
    145           height: height / 2 - 2 + "px",
    146           top: 0,
    147         };
    148       }
    149       if (position === "bottom") {
    150         rt = {
    151           height: height / 2 + 1 + "px",
    152           bottom: 0,
    153         };
    154       }
    155       return rt;
    156     },
    157     isFirst(id) {
    158       return (
    159         this.list.length > 1 && this.list.map((x) => x.id).indexOf(id) === 0
    160       );
    161     },
    162     isLast(id) {
    163       return (
    164         this.list.length > 1 &&
    165         this.list.map((x) => x.id).indexOf(id) === this.list.length - 1
    166       );
    167     },
    168   },
    169 };
    170 </script>
    171 
    172 <style lang="scss" scoped>
    173 .TreeRight {
    174    100%;
    175   height: 100%;
    176   overflow: auto;
    177   p {
    178     margin: 0;
    179     font-size: 13px;
    180   }
    181   display: flex;
    182   .father {
    183      70px;
    184     background-color: red;
    185     padding: 100px 10px;
    186   }
    187   .childs {
    188     .child {
    189       display: flex;
    190       background-color: #fff;
    191       .child-item {
    192         display: flex;
    193         align-items: center;
    194         margin: 10px 0;
    195         .childname {
    196           .content-box {
    197             text-align: left;
    198             border: 1px solid #e8e8e8;
    199             padding: 10px;
    200             height: 100px;
    201             border-radius: 2px;
    202              100%;
    203             box-shadow: 0 2px 4px 0 rgba(181, 181, 181, 0.7);
    204           }
    205           cursor: pointer;
    206           height: 100%;
    207           display: flex;
    208           align-items: center;
    209            220px;
    210           text-align: center;
    211           justify-content: center;
    212           position: relative;
    213           padding: 10px 0;
    214           .position-arrow {
    215             position: absolute;
    216             left: -22px;
    217           }
    218           .position-top {
    219             position: absolute;
    220              3px;
    221             background-color: #fff;
    222             left: -23px;
    223             height: 10px;
    224           }
    225         }
    226         .childarrow {
    227           height: 100%;
    228           display: flex;
    229           align-items: center;
    230         }
    231       }
    232     }
    233     .child-children {
    234       display: flex;
    235       flex-direction: column;
    236       justify-content: center;
    237     }
    238   }
    239 }
    240 </style>
    View Code

    父亲组件引用方式如下:

     1 <template>
     2   <div>
     3     <right-tree
     4       v-if="list && list.length"
     5       :list="list"
     6       :showfields="showFields"
     7     ></right-tree>
     8   </div>
     9 </template>
    10 <script>
    11 import RightTree from '../components/RightTree'
    12 export default {
    13     components:{
    14         RightTree,
    15     },
    16     data(){
    17         return{
    18             list: [//datasource
    19                 {
    20                     id: '1',
    21                     name: 'span1',
    22                     serviceId: 'service1',
    23                     children: [
    24                         {
    25                             id: '1-1',
    26                             name: 'user',
    27                             serviceId: 'service-user',
    28                             children: [
    29                                 {
    30                                     id: '1-1-1',
    31                                     name: 'shop',
    32                                     serviceId: '18',
    33                                     children: [
    34                                         {
    35                                             id: '1-1-1-1',
    36                                             name: 'common',
    37                                             serviceId: 'common-service',
    38                                         },
    39                                     ],
    40                                 },
    41                                 {
    42                                     id: '1-1-2',
    43                                     name: 'account1',
    44                                     serviceId: 'account-service',
    45                                 },
    46                                 {
    47                                     id: '1-1-3',
    48                                     name: 'account2',
    49                                     serviceId: 'account-service',
    50 
    51                                 },
    52                                 {
    53                                     id: '1-1-4',
    54                                     name: 'account3',
    55                                     serviceId: 'account-service',
    56                                 },
    57                             ],
    58                         },
    59                         {
    60                             id: '1-2',
    61                             name: 'truck',
    62                             serviceId: 'truck-pay',
    63                             work: 'web',
    64                         },
    65                     ],
    66                 },
    67             ],
    68             showFields: [
    69                 {
    70                     name: '服务名称:',
    71                     key: 'name',
    72                 },
    73                 {
    74                     name: '服务编号:',
    75                     key: 'serviceId',
    76                 },
    77             ],
    78         }
    79     },
    80     methods:{
    81 
    82     },
    83     
    84 }
    85 </script>
    View Code

    其实就是用leader-line-vue绘制了引导线,leader-line-vue的功能还是蛮强大的,想了解更深,可以参考官网:https://www.npmjs.com/package/leader-line-vue

  • 相关阅读:
    shellscript 02 find & xargs
    PL/SQL exception
    PL/SQL 游标
    Eclipse
    【数据存储】操作资源文件
    【AsynTask】Android异步加载一张图品
    【数据存储】利用IO流操作文件
    【数据存储】DOM操作
    【特效】手指滑动:水波纹
    【数据存储】SAX操作
  • 原文地址:https://www.cnblogs.com/yuwenjing0727/p/14921712.html
Copyright © 2020-2023  润新知