You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

310 lines
8.0 KiB

<template>
<view class="content">
<view class="mix-tree-list">
<block v-for="(item, index) in treeList" :key="index">
<view
class="mix-tree-item flex-between"
:style="[{
paddingLeft: item.rank*15 + 'px',
zIndex: item.rank*-1 +50
}]"
:class="{
border: treeParams.border === true,
show: item.show,
last: item.lastRank,
showchild: item.showChild
}"
@click.stop="treeItemTap(item, index)"
>
<view class="">
<image class="mix-tree-icon" :src="item.lastRank ? treeParams.lastIcon : item.showChild ? treeParams.currentIcon : treeParams.defaultIcon"></image>
{{item.name}}
</view>
<view v-if="item.account" @click="changeRund(item)" class="">
<image class="img-round" :src="item.checked?checkedRund:uncheckRund" mode=""></image>
<!-- <image class="img-round" src="" mode=""></image> -->
</view>
</view>
</block>
</view>
</view>
</template>
<script>
export default {
props: {
list: { // 数据来源
type: Array,
default(){
return [];
}
},
params: {
type: Object,
default(){
return {}
}
},
fliter:{// 搜索传值
type:String,
},
multiple:{// 多选是否开启
type:Boolean,
default(){
return false
}
},
limit:{// 限制一次选择多少个
type:Number,
default(){// 默认是99个,相当于不做限制了
return 99
}
},
unChecked:{// 判断固定评委和摇号评委是否重复,取消该勾选
type:String,
default(){
return ''
}
}
},
data() {
return {
treeList: [],
treeParams: {
defaultIcon: '../../static/img/defaultIcon.png',
currentIcon: '../../static/img/currentIcon.png',
lastIcon: '',
border: false
},
bSearch:'',
aSearch:'',
colonData:'',
checkedRund:'../../static/img/btn_pre.png',// 选中样式
uncheckRund:'../../static/img/btn_per_un.png',// 没选中样式
idsList:[],// ids
cloneData:[],// 克隆数据
nameList:[],// 名称数组
}
},
watch: {
list(list){
// console.log('重置了列表')
this.treeList = []// 重置list列表
this.treeParams = Object.assign(this.treeParams, this.params);
this.renderTreeList(list);
this.$forceUpdate()
},
fliter(val,old){
if(!val){// 深拷贝还原
// 把ids的值赋值给原数组
this.cloneData.forEach(e=>{
if(this.idsList.includes(e.id)){
e.checked = true
}
})
this.treeList = this.cloneData
}else{// 执行搜索
this.cloneData.forEach(e=>{
if(this.idsList.includes(e.id)){
e.checked = true
}
})
this.treeList = this.cloneData
let arrData = JSON.parse(JSON.stringify(this.treeList))
this.treeList = []
arrData.forEach(e=>{// 处理传值
if (e.name.includes(val)){
e.show = true
e.showChild = true
this.treeList.push(e)
}
})
this.$forceUpdate()
// this.treeList = [...new Set(this.treeList)]
}
},
// 取得需要删除的值,匹配删除该值
// 需要阻断取消勾选
unChecked(val){
if(!val||val=='') return
this.changeChecked(val)
}
},
methods: {
// 判断固定和摇号评委重复时的取消勾选功能--
changeChecked(name){
this.treeList.forEach(e=>{
if(e.name == name){
e.checked = false
// 若要删除id,在这里加上即可
if(this.nameList.indexOf(name)!==-1){
this.nameList.splice(this.nameList.indexOf(name),1)// 删除对应的名称
}
if(this.idsList.indexOf(e.id)!==-1){
this.idsList.splice(this.idsList.indexOf(e.id),1)
}
}
})
this.$emit('checkedRund',this.nameList,this.idsList)// 传递到父级当前选中的
this.$emit('delstr','')// 改变值
},
//扁平化树结构
renderTreeList(list=[], rank=0, parentId=[]){
// 构思:首先循环把每一个item先push
// 再判断item是否有children,有的话再
list.forEach(item=>{
this.treeList.push({
id: item.id,
name: item.name,
parentId, // 父级id数组
rank, // 层级
showChild: false, //子级是否显示
show: rank === 0 ,// 自身是否显示
// 自定义
account: item.account?item.account:false,// 是否展示勾选
// 展示勾选否 , 预留勾选传值功能,未做
checked:this.checkedIDS?this.checkedIDS.map(e=>{if(e===item.id){return true }else{return false}}):false
})
if(Array.isArray(item.children) && item.children.length > 0){
let parents = [...parentId];
parents.push(item.id);
this.renderTreeList(item.children, rank+1, parents);
}else{
this.treeList[this.treeList.length-1].lastRank = true;
}
})
this.cloneData = JSON.parse(JSON.stringify(this.treeList))// 深度克隆当前的数组
},
// 点击树节点
treeItemTap(item){
let list = this.treeList;
let id = item.id;
if(item.lastRank === true){
//点击最后一级时触发事件
this.$emit('treeItemClick', item);
return;
}
item.showChild = !item.showChild;
list.forEach(childItem=>{
if(item.showChild === false){
//隐藏所有子级
if(!childItem.parentId.includes(id)){
return;
}
if(childItem.lastRank !== true){
childItem.showChild = false;
}
childItem.show = false;
}else{
if(childItem.parentId[childItem.parentId.length-1] === id){
childItem.show = true;
}
}
})
},
// 点击圆圈事件
changeRund(item){
if(this.multiple){// 多选操作
// 重复选中的判断
if(this.idsList.includes(item.id)){// 如果包含了已有的id(人员可能重复)
item.checked = false
// 执行删除操作
this.idsList.splice(this.idsList.indexOf(item.id),1)
this.nameList.splice(this.nameList.indexOf(item.name),1)
}else{
if(this.limit){// 限制选中多少个
if( this.idsList.length>=this.limit){
this.idsList.splice(this.limit,1)
this.nameList.splice(this.limit,1)
return uni.showToast({
title:`请不要选择超过${this.limit }个!`,
icon:'none'
})
}
}
item.checked = !item.checked
if(item.checked){// push
this.idsList.push(item.id)
this.nameList.push(item.name)
}else{// 删除
this.idsList.splice(this.idsList.indexOf(item.id),1)
this.nameList.splice(this.nameList.indexOf(item.name),1)
}
}
// 记录所有的数组?
}else{// 单选操作
item.checked = !item.checked// 切换选中状态
if(item.checked){// push
this.idsList.push(item.id)
this.nameList.push(item.name)
}else{// 删除操作
this.idsList.splice(this.idsList.indexOf(item.id),1)
this.nameList.splice(this.nameList.indexOf(item.name),1)
}
// console.log('单选',this.idsList,this.treeList)
if(this.idsList.length>1){
this.treeList.forEach(e=>{
if(e.id === this.idsList[0]){
e.checked = false// 变成false
}
})
this.nameList.splice(0,1)// 名称
this.idsList.splice(0,1)// 删除前一个
// this.$emit('checkedRund',item,this.idsList)// 传递到父级当前选中的
}
}
this.$emit('checkedRund',this.nameList,this.idsList)// 传递到父级当前选中的
return
},
}
}
</script>
<style>
.mix-tree-list{
display: flex;
flex-direction: column;
padding-left: 30upx;
}
.mix-tree-item{
display: flex;
align-items: center;
font-size: 30upx;
color: #333;
height: 0;
opacity: 0;
transition: .2s;
position: relative;
}
.mix-tree-item.border{
border-bottom: 2rpx solid #eee;
}
.mix-tree-item.show{
height: 80upx;
opacity: 1;
}
.mix-tree-icon{
width: 26upx;
height: 26upx;
margin-right: 8upx;
opacity: .9;
}
.mix-tree-item.showchild:before{
transform: rotate(90deg);
}
.mix-tree-item.last:before{
opacity: 0;
}
.img-round{
width: 25rpx;
height: 25rpx;
margin-right: 100rpx;
}
</style>