本文若对你有用,给个免费 Star 和关注,持续输出前端各种稀奇古怪的问题
所实现的效果如图
全选.gif
代码如下,注释齐全
- 本段代码用到uview的u-check,一张箭头图片, scss,引入initData,
- 三级全选,所操作的数据为字符串,如 "zjcb,yxhpcb,tghf,ztchf",所有全选数据通过初始化模拟数据实现,如果有现成的数据,改造即可
- cbAll 可以与 cbCheckChange 结合,但是会使cbCheckChange 更复杂,想实现可以自己动手
<template>
<view class="customize">
<!-- 总全选 -->
<view class="choice-all">
<u-checkbox size='24rpx' label-size="28rpx"
:name="cbData.code"
v-model="cbAll">全选</u-checkbox>
</view>
<view class="choice-check" v-for="cbList in cbDatas.list" :key="cbList.id">
<view class="choice-zjcb" @tap="cbOpenChange(cbList)">
<!-- 二级全选 -->
<view @tap.stop style="width: 300rpx;">
<u-checkbox size='24rpx' label-size="28rpx"
:name="cbList.code"
class='checkBold'
@change='cbCheckChange(cbList, $event)'
v-model="cbList.show"
>{{cbList.name}}</u-checkbox>
</view>
<view style="margin-right: 20rpx;">
<!-- 此处为右侧旋转箭头图片 -->
<image :style="{transform: cbList.open?'rotate(0deg)':'rotate(180deg)', transition: 'all .3s'}" class="checkIcon" src="//image.ecbis.com/bi/wechat/images/zdysc_CaretUp.png"></image>
</view>
</view>
<view class="" v-for="(cateItem, cateIndex) in cbList.list" :key="cateItem.id" v-if="cbList.open">
<view class="choice-zjcb2" @tap="cbOpenChange(cateItem)">
<!-- 三级全选 -->
<view @tap.stop="">
<u-checkbox size='24rpx' label-size="28rpx" :name="cateItem.code"
v-model="cateItem.show" @change='cbCheckChange(cateItem, $event, cbList)'
>{{cateItem.name}}</u-checkbox>
</view>
<view style="margin-right: 20rpx;" v-if="cateItem.list.length>0">
<image :style="{transform: cateItem.open?'rotate(0deg)':'rotate(180deg)', transition: 'all .3s'}" class="checkIcon" src="//image.ecbis.com/bi/wechat/images/zdysc_CaretUp.png"></image>
</view>
</view>
<view class="content-checkbox" v-if="cateItem.open">
<view class="checkbox-box">
<!-- 单个复选 -->
<u-checkbox size='24rpx' active-color='#6285F0' class="checkbox ellips" label-size="28rpx"
v-for="(item, index) in cateItem.list" :key="index"
@change="rlChange($event, cateItem, cbList)" v-model="item.show" :name="item.code"
>{{item.name}}</u-checkbox>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import initData from './initData.js'
export default {
name: 'customize',
data() {
return {
// 全选
queryArr: [],
list: initData.list,
cbData: initData.cbData,
};
},
methods:{
// 全选or全不选
checkBoxAll(done, data){
if(!!data){
data.forEach((item)=>{ item.show = done })
}
},
// 选择的单个复选框
rlChange($event, cateItem, longItem){
this.queryArrEvent($event)
// 全选反选,访客,成本
this.$nextTick(()=>{
// 全选二级
this.doneLength(cateItem)
// 全选总
this.doneLength(longItem)
})
},
// 全选反选
doneLength(item){
if(item.list&&item.list.length>0){
let done = item.list.reduce((pre,current)=>pre+(current.show?1:0),0)
let length = item.list.length
item.show = done===length&&length>0?true:false
}
},
// 成本二三级标题展开
cbOpenChange(item){
if(Object.prototype.hasOwnProperty.call(item, 'open')){
item.open = item.open?false:true
}
},
// 成本二级三级全选
cbCheckChange(item, $event, cbList){
this.checkAll($event.value, item.list)
if(!!item.list){
item.list.forEach((cateItem)=>{
if(!!cateItem.list){
this.checkAll(cateItem.show, cateItem.list)
cateItem.list.forEach((goods)=>{
if(!!goods.list){
this.checkAll(goods.show, goods.list)
}
})
}
})
}
// 成本二级三级反选
this.$nextTick(()=>{
if(!!cbList){
// console.log($event)
this.queryArrEvent($event)
this.doneLength(cbList)
}
})
},
// 点击选中,添加字符串
queryArrEvent(event){
this.queryArr = this.queryArr.length===0?this.showArr:this.queryArr
if(event.value){
if(!this.queryArr.includes(event.name)){
this.queryArr.push(event.name)
}
}else{
if(this.queryArr.includes(event.name)){
this.queryArr.forEach((value, index)=>{
if(value === event.name){
this.queryArr.splice(index,1)
}
})
}
}
},
// 点击全选, 全选下方复选框都选择
checkAll(done, data){
if(!data) return
this.checkBoxAll(done, data)
this.queryArr = this.queryArr.length===0?this.showArr:this.queryArr
data.forEach(item=>{
if(!!item.show){
if(!this.queryArr.includes(item.code)){
this.queryArr.push(item.code)
}
}else{
if(this.queryArr.includes(item.code)){
this.queryArr = this.queryArr.filter((value)=>{
return value !== item.code
})
}
}
})
},
// 包括
showArrIncludes(item){
if(!!this.showArr){
if(this.showArr.includes(item.code)){
item.show = true
}else {
item.show = false
}
}
}
},
computed:{
// 确定哪些数据需要展示
showArr: {
get(){
let showArr = []
if(this.queryArr.length>0){
showArr = this.queryArr
}
return showArr
},
set(value){
return value
}
},
// 成本展示 数据处理
cbDatas() {
let cbData = this.cbData
if(cbData.list.length>0){
cbData.list.forEach((cbItem,cbIndex)=>{
this.showArrIncludes(cbItem)
cbItem.list.forEach((item)=>{
this.showArrIncludes(item)
if(item.list){
item.list.forEach((goods)=>{
this.showArrIncludes(goods)
this.doneLength(goods)
})
}
this.doneLength(item)
})
this.doneLength(cbItem)
})
}
return cbData
},
// 成本全选
cbAll: {
get(){
let done = this.cbData.list.reduce((pre,current)=>pre+(current.show?1:0),0)
let length = this.cbData.list.length
return done===length&&length>0
},
set(value){
this.checkAll(value, this.cbData.list)
this.cbData.list.forEach((item)=>{
if(!!item.list){
this.checkAll(item.show, item.list)
item.list.forEach((goods)=>{
if(!!goods.list){
this.checkAll(goods.show, goods.list)
}
})
}
})
}
}
},
}
</script>
<style lang="scss" scoped>
.customize { margin-top: 200rpx; }
.choice-all { height: 68rpx; padding: 12rpx 25rpx 0; box-sizing: border-box; }
.choice-zjcb, .choice-zjcb2 { height: 72rpx; padding: 12rpx 30rpx; background-color: rgba(238, 240, 254, 0.4); box-sizing: border-box; display: flex; justify-content: space-between; line-height: 60rpx; }
.choice-check { box-sizing: border-box;padding: 0 16rpx;
.content-checkbox { padding: 12rpx 25rpx 0; box-sizing: border-box;
.checkbox-box { display: flex; justify-content: space-between; flex-wrap: wrap; padding: 8rpx 50rpx 16rpx;
.checkbox { width: 50%; padding: 14rpx 0;box-sizing: border-box;
}
}
}
}
.choice-zjcb2 { padding: 12rpx 50rpx; }
/deep/.checkBold .u-checkbox__label{ font-weight: 600; }
.checkIcon { width: 35rpx; height:35rpx; }
</style>
- 同级initData.js
const initData = {
cbData: {
code: 'cb',
id: '23000',
show: false,
list: [
{ id: '23100', code:"zjcb", name: '直接成本', show: false, open:true,
list: [
{ id: '23700', code:"yxhpcb", name: '货品成本', show: false, open: false, },
{ id: '23200', code:"tghf", name: '推广花费', show: false, open: true,
list: [
{ id:'23201', code:"ztchf", name: '直通车花费', show: false },
{ id:'23202', code:"cjtjhf", name: '超级推荐花费', show: false },
{ id:'23203', code:"zzhf", name: '钻展花费', show: false },
{ id:'23204', code:"pxbhf", name: '品销宝花费', show: false },
{ id:'23205', code:"jhshf", name: '聚划算花费', show: false },
],
},
{ id: '23300', code:"yxhf", name: '营销花费', show: false, open: true,
list: [
{ id:'23301', code:"wxdhf", name: '无效单花费', show: false },
{ id:'23302', code:"shhf", name: '售后花费', show: false },
],
},
],
},
{ id: '24101', code:"jjcb", name: '间接成本', show: false, open:true,
list: [
{ id: '24200', code:"jtcb", name: '均摊成本', show: false, open: false, },
],
},
],
},
}
export default initData