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.
311 lines
8.0 KiB
311 lines
8.0 KiB
3 years ago
|
<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>
|