这次是结合vue 写的一个移动端树形图,主要实现的功能: 把勾选人或者部门的id传给后台

数据的基本结构

[
    {
        "children": [
            {
                "children": [
                    {
                        "children": [],
                        "name": "教师1",
                        "pid": "1133184954990067712",
                        "id": "1133186086739116032"
                    },
                    {
                        "children": [],
                        "name": "教师2",
                        "pid": "1133184954990067712",
                        "id": "1133186086739116032"
                    }
                ],
                "name": "在编教师",
                "pid": "1133184954990067712",
                "id": "1133186086739116032"
            },
            {
                "children": [],
                "name": "部门自聘人员",
                "pid": "1133184954990067712",
                "id": "1133187313757585408"
            }
        ],
        "name": "教师",
        "pid": "-1",
        "id": "1133184954990067712"
    },
    {
        "children": [
            {
                "children": [
                    {
                        "children": [],
                        "name": "本科生1",
                        "pid": "1133184954990067712",
                        "id": "1133186086739116032"
                    },
                    {
                        "children": [],
                        "name": "本科生2",
                        "pid": "1133184954990067712",
                        "id": "1133186086739116032"
                    }
                ],
                "name": "本科生",
                "pid": "1133185731036971008",
                "id": "1133187654939049984"
            },
            {
                "children": [],
                "name": "研究生",
                "pid": "1133185731036971008",
                "id": "1133189438256447488"
            }
        ],
        "name": "学生",
        "pid": "-1",
        "id": "1133185731036971008"
    }
]

基本实现的效果图

一 这是刚刚进来初始化的效果图
在这里插入图片描述

二,点击进入下一级(注: 下一级是根据childer里是否有值来判断是否显示)
在这里插入图片描述
在这里插入图片描述

主要代码实现

<template>
  <div  class="personnelTree" :class="{'slideUp': personnelTree}">
        <div class="tree_herd">
            <div class="backTitle" >
                <span v-if="!twoMenuShow" @click.stop='cancelChose'>取消</span>
                <span v-else @click.stop='twoMenuShow = false'>返回</span>
            </div>
            <div class="newTitle">
                <span>选择{{peoperTitle}}</span>
            </div>
            <div class="sendTitle" @click.stop="confirmAdd" v-show="!twoMenuShow">
                <span>确定</span>
            </div>
        </div>
        <!-- 一级菜单 -->
        <div class="menu flex flex-y justify-start" v-show="!twoMenuShow">
            <div class="mainContent flex-1">
                <div class="container">
                    <div @click="newPersonnel" class="choice">
                        <div class="titlePer" style="width:90%;"> 
                            <span>选择新的{{peoperTitle}}</span> 
                        </div>
                        <img src="../../assets/peg/u5769.png" alt="" style="width:10px;height:15px;">
                       
                    </div>
                  
                </div>
                <div class="container_title">
                    <div class="titlePer" v-if="selectedReceiver.length != 0">
                        <span>已选的{{peoperTitle}}</span>
                    </div>
                </div>
                <div class="container">
                    <!-- <div class="choice">
                        <div class="titlePer" v-if="selectedReceiver != ''">
                             <input type="checkbox" @click="checkAll($event)"  ref="quan">
                            <span style="margin-left:5px;width:60%">全选</span>
                        </div>
                    </div> -->
                </div>
                <div class="container">
                    <div class="choice" v-for="(item, index) in selectedReceiver" :key="index">
                        <div class="titlePer">
                            <!-- <input type="checkbox" class="checkItme" :checked="item.checked" @change="selectChange(item,index)" ref="checkItme"> -->
                            <span style="margin-left:15px;width:60%">{{item.name}}</span>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        <!-- 二级菜单 -->
        <div id="twoMenu" class="menu flex flex-y justify-start" v-show="twoMenuShow">
            <div class="mainContent flex-1">
                <!-- 顶部搜索 -->
                <div class="topSearch">
                    <input type="text" class="searchInput" :class="{'alien_center': search}" placeholder="搜索" @focus="search = true" @blur="search = false">
                    <img src="../../assets/search.png" v-show="!search" class="searchIcon" alt="">
                </div>
                <div class="container" style="margin-top:0;"> 
                    <div class="choice">
                        <div class="titlePer">
                            <span style="color:#A1A1A1;" @click.stop="contacts">联系人</span>
                            <div style="display: inline-block;" v-for="(item, index) in currentGroup" :key="index">
                                <span style="margin:0">/</span>
                                <span style="margin:0" @click.stop="hierarchy(index,item)">{{item.name}}</span>
                            </div>
                        </div>
                    </div>
                </div>
                <div class="container">
                    <div class="choice">
                        <div class="titlePer">
                        <input type="checkbox" v-model='allCheck' @change="allChange"  ref="quan">
                        <span style="margin-left:5px;width:60%">全选</span>
                    </div>
                    </div>
                </div>
                <div class="container">
                   <div v-for="(item, index) in depData" :key="index" class="choice">
                       <div class="titlePer">  
                            <input type="checkbox" v-model="item.checked" @change="changeSelected(index,item)"> 
                            <span style="margin-left:5px;width:88%" >{{item.name}}</span>
                       </div>
                       <div class="right_Per" v-if="item.children.length > 0 && !item.checked" @click="nextLevel(item)" >
                           <img src="../../assets/peg/u6147.png" alt="">
                           <label style="color:#3399FF">下级</label>
                       </div>
                        
                   </div>
                </div>
            </div>
        </div>
        
  </div>
</template>

<script>
import { format } from 'path';
import $api from '../../api/peg.js'
import { isRegExp, debug, debuglog } from 'util';
import { fail } from 'assert';
import { constants } from 'fs';
export default {
    data (){
        return{
            search: false,
            twoMenuShow: false,
            checkData: [],
            dataNumber:'',
            item:'',
            peoperTitle: '', // 标题
            selectedMember: [], // 选中的成员列表
            selectedReceiver:[],// 接收人
            copySelectedReceiver:[], // 抄收人
            selectedorgan:[],
            currentGroup: [],
            depData: [],
            allCheck: false, // 全选
            OriginalDepData: [], // 原始数据
            selectType: '',
            checked:'',
            menuList: []

        }
    },
    mounted () {
        this.findRoleGroups() 
    },
    // 监视双向绑定的数据数组
    watch: { 
        allCheck () {
            for(var i = this.currentGroup.length - 1; i >= 0; i-- ){
               if(!this.currentGroup[i].checked) {
                   if(i != this.currentGroup.length - 1) {
                       this.selectedReceiver.length = this.selectedReceiver.length - 1
                       this.selectedReceiver.push(this.currentGroup[i + 1])
                   }
                   break
               } else {
                    try {
                        let children = this.currentGroup[i - 1].children
                        let num = 0
                        children.forEach(item => {
                            if(item.checked) {
                                num++
                            }
                        })
                        if(num == children.length) {
                            this.currentGroup[i - 1].checked = true
                        }
                    } catch (error) {
                        
                    }
               }
           }
        }
    },
    methods: {
        
        /**
         * 全选按钮
         */
        allChange () {
            if(this.currentGroup.length == 0){
                this.depData.forEach(item => {
                    item.checked = this.allCheck
                    this.selectedReceiver.forEach((item1,index) => {
                        if(item1.id == item.id) {
                            this.selectedReceiver.splice(index, 1)
                        }
                    })
                    if(item.checked){
                        this.selectedReceiver.push(item)  
                    }else{
                        this.selectedReceiver.forEach((item1,index) => {
                            if(item1.id == item.id) {
                                this.selectedReceiver.splice(index, 1)
                            }
                        })
                    }
                })
                this.menuList = []
                this.addNode(this.selectedReceiver)
                console.log(this.menuList)
                this.menuList.forEach(selectItem =>{
                    selectItem.checked = false
                    this.selectedReceiver.forEach((originItem,idx) =>{
                        if(selectItem.id == originItem.id){
                            this.selectedReceiver.splice(idx, 1)
                        }
                    })
                    
                })
            }else{
                this.depData.forEach(item => {
                    item.checked = this.allCheck
                    this.selectedReceiver.forEach((item1,index) => {
                        if(item1.id == item.id) {
                            this.selectedReceiver.splice(index, 1)
                        }
                    })
                })
                if(this.allCheck){
                    let data = this.currentGroup[this.currentGroup.length - 1]
                    data.checked = this.allCheck
                    this.selectedReceiver.push(this.currentGroup[this.currentGroup.length - 1]) 
                }else{
                    this.currentGroup.forEach(item =>{
                        console.log(item)
                         this.selectedReceiver.forEach((item1,index) =>{
                             if(item1.id == item.id) {
                                this.selectedReceiver.splice(index, 1)
                            }
                         })
                    })
                }
            }
        },
        /**
         * 单选按钮
         */
        changeSelected (index,item) {
            
            // this.selectedReceiver.forEach(item =>{
            //     console.log(item.children)
            // })
            if(this.currentGroup == 0){
                let num = 0
                this.depData.forEach(i => {
                    if(i.checked) {
                        num++ 
                    }
                })
                this.selectedReceiver.forEach((itemP,idx) => {
                    if(itemP.id == item.id) {
                        this.selectedReceiver.splice(idx, 1)
                    }
                })
                if(item.checked){
                    this.selectedReceiver.push(item)
                } else {
                    this.selectedReceiver.forEach((itemP,idx) => {
                        if(itemP.id == item.id) {
                            this.selectedReceiver.splice(idx, 1)
                        }
                    })
                }
                if(num == this.depData.length) {
                    this.allCheck = true
                } else {
                    this.allCheck = false
                    this.menuList = []
                    this.addNode(this.selectedReceiver)
                    console.log(this.menuList)
                    this.menuList.forEach(selectItem =>{
                        selectItem.checked = false
                        this.selectedReceiver.forEach((originItem,idx) =>{
                            if(selectItem.id == originItem.id){
                                this.selectedReceiver.splice(idx, 1)
                            }
                        })
                    })
                }
                
            }else{
                let number = 0
                this.depData.forEach(i => {
                    if(i.checked) {
                        number++ 
                    }
                })
                if(number == this.depData.length) {
                    this.allCheck = true
                    // 清空相同字段
                    this.depData.forEach(item =>{
                        this.selectedReceiver.forEach((itemP,idx) => {
                            if(itemP.id == item.id) {
                                this.selectedReceiver.splice(idx, 1)
                            }
                        })
                    })
                    let data = this.currentGroup[this.currentGroup.length - 1]
                    data.checked = this.allCheck
                    this.selectedReceiver.push(this.currentGroup[this.currentGroup.length - 1]) 
                } else {
                    this.allCheck = false
                    this.depData.forEach(item =>{
                        this.selectedReceiver.forEach((item1,index) => {
                            if(item1.id == item.id) {
                                this.selectedReceiver.splice(index, 1)
                            }
                        })
                        if(item.checked){
                            this.selectedReceiver.push(item)
                        } else {
                            this.selectedReceiver.forEach((item2,idx) => {
                                if(item2.id == item.id) {
                                    this.selectedReceiver.splice(idx, 1)
                                }
                            })
                        }
                    })
                    this.currentGroup.forEach(item =>{
                        this.selectedReceiver.forEach((item1,index) =>{
                            if(item1.id == item.id) {
                                this.selectedReceiver.splice(index, 1)
                            }
                        })
                    })
                    this.menuList = []
                    this.addNode(this.selectedReceiver)
                    console.log(this.menuList)
                    this.menuList.forEach(selectItem =>{
                        selectItem.checked = false
                        this.selectedReceiver.forEach((originItem,idx) =>{
                            if(selectItem.id == originItem.id){
                                this.selectedReceiver.splice(idx, 1)
                            }
                        })
                        
                    })
                }
            }
        },
        /**
         * 遍历循环所有子节点里的数据
         */
        addNode(item){
            for (let i = 0; i < item.length; i++) {
                if (item[i].children) {
                    var oChild = item[i].children;
                    for (let j = 0; j < oChild.length; j++) {
                        this.menuList.push(oChild[j])
                    }
                    this.addNode(oChild);
                }
            }
        },
        /**
         * 点击取消
         */ 
        cancelChose () {
            this.depData = this.OriginalDepData
            this.receiverMembers()
            this.$emit('selectedMember', false,  false)
        },
        /**
         * 点击选择新的接收人
         */
        newPersonnel () {
            this.twoMenuShow = true
            this.depData = this.OriginalDepData
            this.currentGroup = []
            this.allCheck = false
            let checkedNum = 0
            console.log(this.depData,this.selectedReceiver)
            this.depData.forEach(item1 => {
                item1.checked = false
                this.selectedReceiver.forEach(item2 => {
                    if(item1.id == item2.id){
                        item1.checked = true
                        checkedNum ++
                    }
                })
            })
            this.allCheck = this.depData.length == checkedNum ? true : false
        },
        /**
         * 点击联系人
         */
        contacts () {
            this.depData = this.OriginalDepData
            this.currentGroup = [] 
            this.allCheck = false
            let checkedNum = 0
            this.depData.forEach(item1 => {
                item1.checked = false
                this.selectedReceiver.forEach(item2 => {
                    if(item1.id == item2.id){
                        item1.checked = true
                        checkedNum ++
                    }
                })
            })
            this.allCheck = this.depData.length == checkedNum ? true : false
        },
        /**
         * 点击其他层级
         */
        hierarchy(index,item){
            if(this.currentGroup.length-1 == index){
               return
            }
            let children =[]
            children = this.currentGroup.splice(index + 1, this.currentGroup.length - 1 -index)
            this.depData = item.children
            this.allCheck = false
            let checkedNum = 0
            this.depData.forEach(item1 => {
                // item1.checked = false
                if(item1.checked) {
                    checkedNum ++
                }
                this.selectedReceiver.forEach(item2 => {
                    if(item1.id == item2.id){
                        item1.checked = true
                        
                    }
                })
            })
            if(checkedNum == this.depData.length){
                this.allCheck = true
                this.depData.forEach(item =>{
                    this.selectedReceiver.forEach((itemP,idx) => {
                        if(itemP.id == item.id) {
                            this.selectedReceiver.splice(idx, 1)
                        }
                    })
                })
                let data = this.currentGroup[this.currentGroup.length - 1]
                data.checked = this.allCheck
                this.selectedReceiver.push(this.currentGroup[this.currentGroup.length - 1]) 
            }else{
                this.allCheck = false
            }
        },
        /**
         * 点击下一级
         */
        nextLevel (data) {
            this.allCheck = false
            this.currentGroup.push(data)
            this.depData = data.children
            let checkedNum = 0 
            this.depData.forEach(item1 => {
                item1.checked = false
                this.selectedReceiver.forEach(item2=> {
                    if(item2.id && item1.id == item2.id){
                        item1.checked = true;
                        checkedNum++

                    }
                })
            })
            this.allCheck = this.depData.length == checkedNum ? true : false
            console.log('路径:', this.currentGroup)
        },
        /**
         * 点击确定
         */
        confirmAdd () {
            把勾选的值或者部门添加到selectedReceiver数组里
        },
        /**
         *  获取角色群组
         */
        findRoleGroups () {
            $api.findRoleGroups().then(res => {
                if (res.status == 200) {
                    this.depData = res.data.data
                    this.OriginalDepData = res.data.data
                }
            })
        }
    }
}
</script>
</style>
Logo

前往低代码交流专区

更多推荐