# vue组件中的树结构

# 父组件

 <div class="addresslist-bottom-all ors" style="display:block">
   <template v-for="(item,index) in bolgs">
		<tree-menu 
		@treechat="chatShow"
		:label="item.groupname" 
		:nodes="item.children"
		:user="item.user"
		:depth="0"
		:key="index"
	  ></tree-menu>
 </template>
<template>

   <div class="tree-menu">
    
     <div :style="indent" @click="toggleChildren" class="dep">
         <span v-if="showChildren">-</span>
         <span v-else>+</span>
         {{ label }}
            
     </div>

     <div v-for="(item,index) in user" class="peoples" 
			v-if="showChildren" @mouseover="treeblock($event)" @mouseout="treemiss($event)">
            
            <div class='addresslist-bottom-all-yuan'>
				{{lastzi(item.disname)}}
			</div>
            <div class='addresslist-bottom-all-name' >
				{{item.disname}}
			</div>
            <button class="addresslist-chat"
					@click="chatShows(item.uid,item.disname,item.Landline,item.Ternumber)"
			>
				聊天
			</button>
            <button class="addresslist-call" @click="playtelphones(item.Landline)">
				拨号
			</button>
            
     </div>
	<tree-menu 

		v-if="showChildren"
		v-for="(node,index) in nodes" 
		:nodes="node.children" 
		:user="node.user"
		:label="node.groupname"
		:depth="depth + 1"
		:key="index"
		>

	</tree-menu>
     
     
     

   </div>

 </template>

 <script>

   export default { 

     props: [ 'label', 'nodes', 'user','depth' ],

     data() {

       return { 
           showChildren: false,
       }

     },

     name: 'tree-menu',

     computed: {

       indent() {

         return { transform: `translate(${this.depth * 10}px)` }

       }

     },

     methods: {

       toggleChildren() {

         this.showChildren = !this.showChildren;
         
       },
       treeblock(event){
          
            var s = event.currentTarget;
            // s.getElementsByTagName("button")[0].style.display = "block";
            s.getElementsByTagName("button")[1].style.display = "block";
       },
       treemiss(event){
          
            var s = event.currentTarget;
            // s.getElementsByTagName("button")[0].style.display = "none";
            s.getElementsByTagName("button")[1].style.display = "none";
       },
       chatShows(a,b,c,d){
          
        //   this.$emit("treechat",a,b,c,d)
            this.playchat(this.$parent,a,b,c,d)
      
       },
       playtelphones(a){

            this.playReal(this.$parent,a)
       },
       playReal(obj, a)
       {
           if(typeof obj.playtelphone == 'function')
           {
               obj.playtelphone(a)
               return
           }
           else
           {
             this.playReal(obj.$parent,a)
           }
       },
       playchat(obj,a,b,c,d){
           if(typeof obj.chatShow == 'function')
           {
               obj.chatShow(a,b,c,d)
               return
           }
           else
           {
             this.playchat(obj.$parent,a,b,c,d)
           }
       },
        lastzi(str) {
            return str.charAt(str.length - 1);
        },


     }

   }

 </script>
 <style scoped>
 .dep{
    height: 40px;
    line-height: 40px;
    margin-left: 10px;
    color: #61aedc;
    cursor: pointer;
 }
 .peoples{
    background: #fff;
    height: 74px;
    position: relative;
   
 }
 button{
     display:none;
 }
 </style>
 

总结

递归组件中的name一定需要,否则会报错! 如上name: 'tree-menu'

# vue-treeselect

基于vue2开发的一个结合树结构和select的插件

 <treeselect
  v-model="form.jurisdiction"
  :multiple="true"
  :options="jurisdictionArr"
  :limitText="count => `+${count}`"
  :limit="1"
  placeholder="选择管辖区"
  no-results-text="暂无查询结果"
  @input = 'tfun("jurisdiction")'
  clearAllText=''
/>
  • multiple多选
  • limitText:不展示的选项展示的问题提示,比如+1,默认英文more
  • limit展示几个选项
  • input事件
  • clearAllText:clearable的x按钮上的title
  • :disable-branch-nodes="true" 仅仅子节点(没有children)才可以被选中
import Treeselect from '@riophae/vue-treeselect'
import '@/assets/styles/newtree.css'
components: {
    Treeselect
}
// css为了覆盖框架自带的样式,改写的

因为插件自带的样式不符合要求,改成类似elementui的风格

::v-deep .vue-treeselect__control{
  height: 32px !important;
  display: inline-block !important;
  $width:100%;
  width:$width;
}
::v-deep .vue-treeselect__multi-value-item{
  background: transparent;
  color:#909399;
}
::v-deep .vue-treeselect__control .vue-treeselect__value-remove{
  background: transparent;
  width:100%;
  color:#909399;
  position: relative;
  top:1px;
  display: none;
}
::v-deep .vue-treeselect__control .vue-treeselect__multi-value-label{
  background: transparent;
  line-height: 20px;
  padding:0 !important;
	max-width:80px;
	text-overflow:  ellipsis;
	overflow:hidden;
	white-space:nowrap;
	background: #F4F4F5;
	position: relative;
	top:3px;
	padding-left:4px !important;
	padding-right:4px !important;
 
}
::v-deep .vue-treeselect--has-value .vue-treeselect__multi-value{
  margin-bottom:0 !important;
}


::v-deep .vue-treeselect__multi-value-item-container{
	text-overflow:  ellipsis;
	overflow:hidden;
	white-space:nowrap;
}

::v-deep .vue-treeselect__x{
  width:6px;
  height:6px;
  position: relative;
  right:4px;
  top:-1px;
}
::v-deep .vue-treeselect__multi-value{
  line-height: 32px;
}

::v-deep .vue-treeselect__multi-value-item-container{
  padding-top:0 !important
}

::v-deep .vue-treeselect__limit-tip-text{
  height:14px;
  position: relative;
  bottom:7px;
}
::v-deep .vue-treeselect__control .vue-treeselect__placeholder,::v-deep .vue-treeselect__control .vue-treeselect__single-value {
  line-height: 32px !important;
}
::v-deep .vue-treeselect__control-arrow-container,::v-deep .vue-treeselect__x-container{
  height: 32px !important;
  vertical-align: inherit;
  position: relative;
  top:12px !important;
}
::v-deep .vue-treeselect{
  height:32px !important;
  box-sizing: border-box;
  width:100%;
}

::v-deep .vue-treeselect__multi-value-label,::v-deep .vue-treeselect__multi-value-item { pointer-events: none !important }

::v-deep .vue-treeselect__limit-tip-text{
  margin-left:4px
}

最后更新: 12/10/2021, 8:47:30 AM