uniapp多级全选,三级全选,全选

本文若对你有用,给个免费 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
 
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容