实现效果:
vue代码:
<template>
<div>
<van-popup
v-model="isVanshow"
position="bottom"
:round="true"
@click-overlay="cancel"
>
<div class="personal-box">
<div class="title">{{ title }}</div>
<div
class="person-list"
>
<div class="item-box">
<div v-for="(item,index) in options" :key="index" class="item-wrap" :class="{'backColor':item.backColor}" @click="firstClick(index,item)">
<van-checkbox v-model="item.checked" shape="square" @change="firstChange(index,item)" :class="{'line':item.iconClass === 'line','empty':item.iconClass === 'empty'}">{{item.label}}</van-checkbox>
<van-icon name="arrow" v-if="index"/>
</div>
</div>
<div class="item-box" v-if="options[firstIndex]">
<div v-for="(s,index) in options[firstIndex].children" :key="index" class="item-wrap">
<van-checkbox v-model="s.checked" shape="square" @change="secChange(index,s)" :class="{'line':s.iconClass === 'line' && !index,'empty':s.iconClass === 'empty'}">{{s.label}}</van-checkbox>
</div>
</div>
</div>
<van-tabbar
ref="tabbarHeight"
class="floot-but"
>
<div class="checked-but">
<div
class="but"
@click="cancel"
>取消</div>
<div
class="but sumbit-but"
@click="confirm"
>确认</div>
</div>
</van-tabbar>
</div>
</van-popup>
</div>
</template>
js代码:
<script>
export default {
name: 'selectPopup',
components: {},
data () {
return {
title: '',
isVanshow: false,
selectOneIdList: [],
selectTwoIdList: [],
selectNameList:[],
selectList: [],
firstIndex:1,
options:[]
}
},
mounted () {
},
methods: {
firstClick(i){
if(!i) return
this.firstIndex = i
this.options.map((item,index)=>{
item.backColor = i === index
})
},
firstChange(i,data){
// 第一级全选/非全选 所有一级或二级全选/非全选
if(i === 0){
this.options.map((opt)=>{
opt.checked = data.checked
opt.iconClass = ''
opt.children?.map((row)=>{
row.checked = opt.checked
row.iconClass = ''
})
})
}else{
// 第一级选中/取消,所有子级选中/取消
data.children.map((item)=>{
item.checked = data.checked
})
// 第一级所有的选中/取消,第一级的'全部'选中/取消
let falseNUm = 0
let trueNum = 0
this.options.forEach((row,i)=>{
if(!row.checked && row.iconClass !== 'line' && i){
falseNUm ++
}
if(row.checked && row.iconClass !== 'line' && i){
trueNum++
}
})
if(trueNum === this.options.length-1 || falseNUm === this.options.length-1){
this.options[0].checked = data.checked
this.options[0].iconClass = ''
}else{
this.options[0].iconClass = 'line'
}
}
},
secChange(i,data){
if(i === 0){
// 处理二级的'全部'取消和勾选,对应的兄弟级和父级状态
this.options[this.firstIndex].checked = data.checked
}
else if(!data.checked){
let falseNum = 0
this.options[this.firstIndex].children.map((opt,f)=>{
if(!opt.checked && f){
falseNum ++
}
})
const childLength = this.options[this.firstIndex].children.length-1
if(falseNum === childLength){
// 第二级除了'全部',全部取消,则父级取消,所有兄弟级取消
this.options[this.firstIndex].checked = data.checked
this.options[this.firstIndex].iconClass = ''
this.options[this.firstIndex].children[0].iconClass = ''
// 判断如果此时第一级除了'全部'全取消,则'全部'取消
let falseNUm = 0
this.options.forEach((row,i)=>{
if(!row.checked && row.iconClass !== 'line' && i){
falseNUm++
}
})
if(falseNUm === this.options.length-1){
this.options[0].checked = data.checked
this.options[0].iconClass = ''
}else{
this.options[0].iconClass = 'line'
}
}else{
// 第二级,取消除了'全部'的任何元素,则'全部'显示'-',父级显示'-',第一级的'全部'显示'-'
this.options[this.firstIndex].iconClass = 'line'
this.options[this.firstIndex].children[0].iconClass = 'line'
this.options[0].iconClass = 'line'
}
}
else if(data.checked){
let trueNum = 0
this.options[this.firstIndex].children.map((opt,f)=>{
if(opt.checked && f){
trueNum ++
}
})
const childLength = this.options[this.firstIndex].children.length-1
if(trueNum === childLength){
// 第二级除了'全部',全部选中,则父级选中,所有兄弟级选中
this.options[this.firstIndex].checked = data.checked
this.options[this.firstIndex].iconClass = ''
this.options[this.firstIndex].children[0].iconClass = ''
// 判断如果此时第一级除了'全部'全选中,则'全部'选中
let trueNum = 0
this.options.forEach((row,i)=>{
if(row.checked && row.iconClass !== 'line' && i){
trueNum++
}
})
if(trueNum === this.options.length-1){
this.options[0].checked = data.checked
this.options[0].iconClass = ''
}else{
this.options[0].iconClass = 'line'
}
}else {
// 第二级,选中除了'全部'的任何元素,则'全部'显示'-',父级显示'-',第一级的'全部'显示'-'
this.options[this.firstIndex].iconClass = 'line'
this.options[this.firstIndex].children[0].iconClass = 'line'
this.options[0].iconClass = 'line'
}
}
},
// 取消 关闭弹出框
cancel () {
this.isVanshow = false
this.$emit('cancel')
},
// 确认
confirm () {
this.selectOneIdList = []
this.selectTwoIdList = []
this.selectNameList = []
this.options.forEach((item,index)=>{
if(item.checked && item.iconClass === '' && index){
this.selectOneIdList.push(item.value)
this.selectNameList.push(item.label)
}else{
item.children?.forEach((row,i)=>{
if(row.checked && i){
this.selectTwoIdList.push(row.value)
this.selectNameList.push(row.label)
}
})
}
})
this.isVanshow = false
console.log("selectNameList",this.selectNameList)
this.$emit('confirm', this.selectOneIdList,this.selectTwoIdList,this.selectNameList)
},
// 打开弹出窗
isShow (str,list,name,isFirst) {
this.title = str
this.options= list
this.isVanshow = !isFirst
}
}
}
</script>
css代码:
<style lang='less' scoped>
.personal-box {
display: flex;
flex-direction: column;
.title {
width: 100%;
height: 56px;
border-bottom: 1px solid #e5e5e5;
font-size: 18px;
color: #323233;
font-weight: 600;
padding-left: 16px;
display: flex;
align-items: center;
}
.person-list {
height: 264px;
border-top: 1px solid #ebedf0;
border-bottom: 1px solid #ebedf0;
padding: 5px 16px 0;
box-sizing: border-box;
display: flex;
justify-content: space-around;
.item-box{
font-size: 12px;
width: 50%;
overflow-y: scroll;
overflow-x: hidden;
.item-wrap{
display: flex;
justify-content: space-between;
align-items: center;
height: 32px;
padding: 0 12px;
}
.backColor{
background: #F3F4F7;
}
}
/deep/ .van-checkbox__icon{
width: 16px;
height: 16px;
line-height: 16px;
font-size:16px
}
/deep/ .van-checkbox__icon .van-icon{
width: 16px;
height: 16px;
}
/deep/ .van-checkbox__label{
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
/deep/ .line .van-icon-success:before{
content: "-";
}
/deep/ .line .van-checkbox__icon .van-icon{
color: #fff;
background-color: #1989fa;
border-color: #1989fa;
}
/deep/ .empty .van-icon-success:before{
content: "";
}
/deep/ .empty .van-checkbox__icon--checked .van-icon{
background-color:#ffffff;
border-color: #c8c9cc;
}
}
.floot-but {
display: block;
height: 68px;
box-shadow: 0px -1px 10px rgba(0, 0, 0, 0.03);
position: relative;
.checked-but {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 16px;
box-sizing: border-box;
margin-top: 12px;
.but {
height: 44px;
width: 165.5px;
display: flex;
justify-content: center;
align-items: center;
border: 1px solid #128A78;
border-radius: 23px;
color: #128A78;
}
.sumbit-but {
background: #128A78;
color: #ffffff;
}
}
}
}
</style>
版权声明:本文为weixin_42398301原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。