使用uni-app的checkbox-group自定义不超过5个的多选

前端小白的uni-app艰难学习之路

问题

在开发过程中,我遇到了这样一个功能,用户只能选择不超过5个的选项,看似简单的功能,但却花了我大量的逻辑关系才勉强做出来,功能是实现了,但是代码看着比较繁琐,不过我实在找不到更好的办法了,如果有路过的大神有更好的办法希望可以不吝赐教

解决

1、先写布局

<checkbox-group class="content-class" @change="chooseMaleLike">
        <label class="item" v-for="(item, index) in maleLike" :key="index" :class="{on: item.isChecked}">
          <checkbox :value="item.value"></checkbox>
          <text class="item-text">{{item.text}}</text>
        </label>
      </checkbox-group>

2、在data里定义我们需要的变量

data () {
      return {
        maleLike: [],
        currentArr: [], // 当前用户想要的选项,最大为5
        oldArr: [], // 上一次的返回值
        hasPass: false // 用户之前是否选择过,是为true
      }
    }

3、method里写chooseMaleLike方法

methods: {
      chooseMaleLike: function (e) {
        if (e.detail.value.length > 5) { // 如果选择的个数超过5个
          if (!this.hasPass) { // 当用户选择数量是第一次超过5
            this.hasPass = true
            if (e.detail.value.length > this.oldArr.length) { // 如果当前选择总数大于上一次选择总数(用户没有取消过选择)
              this.currentArr = e.detail.value.slice(0, 5)
              uni.showToast({
                title: '最多5个',
                icon: 'none'
              })
            } else { // 如果当前选择总数小于上一次选择总数(用户取消部分选择)
              let arr = []
              for (var i = 0; i < this.currentArr.length; i++) {
                for (var j = 0; j < 5; j++) {
                  if (this.currentArr[i] === e.detail.value[j]) {
                    arr.push(this.currentArr[i])
                  } else {
                    continue
                  }
                }
              }
              this.currentArr = arr
            }
          } else { // 当用户选择数量不是第一次超过5(这时候change事件的返回值里有不一定是用户想要的值,所以需要做判断)
            if (e.detail.value.length > this.oldArr.length) { // 用户又增加了选项
              let n = e.detail.value.length
              if (this.currentArr.length < 5) {
                this.currentArr.push(e.detail.value[n - 1])
              } else {
                uni.showToast({
                  title: '最多5个',
                  icon: 'none'
                })
              }
            } else { // 用户取消了部分选项
              let arr = []
              for (var i = 0; i < this.currentArr.length; i++) {
                let n = e.detail.value.indexOf(this.currentArr[i])
                if (n !== -1) {
                  arr.push(this.currentArr[i])
                } else {
                  continue
                }
              }
              this.currentArr = arr
            }
          }
        } else { // 如果选择的个数小于等于5
          if (this.hasPass) { // 不是第一次小于5,即之前多选过,后来又取消选择
            if (e.detail.value.length < this.oldArr.length) { // 用户取消了部分选择
              let arr = []
              for (var i = 0; i < this.currentArr.length; i++) {
                let n = e.detail.value.indexOf(this.currentArr[i])
                if (n !== -1) {
                  arr.push(this.currentArr[i])
                } else {
                  continue
                }
              }
              this.currentArr = arr
            } else { // 用户增加选择,增加的新选项在数组最后
              let n = e.detail.value.length
              this.currentArr.push(e.detail.value[n - 1])
            }
          } else { // 是第一次小于5,这个最简单了,直接选了什么就给什么
            this.currentArr = e.detail.value
          }
          
          if (e.detail.value.length === 0) { // 如果用户取消了全部选择,让hasPass为false,即下一次再选时就会判断为第一次选择
            this.hasPass = false
          }
        }
        for (var i = 0, lenI = this.maleLike.length; i < lenI; ++i) { // 给用户的选项添加样式
          this.maleLike[i].isChecked = false;
          for (var j = 0, lenJ = this.currentArr.length; j < lenJ; ++j) {
            if (String(this.maleLike[i].value) === String(this.currentArr[j])) {
              this.maleLike[i].isChecked = true
              break
            }
          }
        }
        this.oldArr = e.detail.value // 把当前返回值赋值给上一次的返回值
      }
    }

下面是css样式代码:

.content-class {
        width: 90%;
        margin: 20upx auto;
        display: flex;
        flex-flow: row wrap;
        justify-content: space-between;
        .item {
          width: 30%;
          height: 60upx;
          font-size: 28upx;
          line-height: 60upx;
          border-radius: 30upx;
          margin-bottom: 20upx;
          text-align: center;
          box-sizing: border-box;
          border: 1upx solid #3f82e7;
          checkbox {
            display: none;
          }
        }
        .on {
          border: none;
          background-color: #3f82e7;
          color: #fff;
        }
      }

最终的效果图
在这里插入图片描述
在这里插入图片描述
如果有不懂的小伙伴可以自己打印一下做判断的几个变量,应该就能懂我为什么写这么多判断了,代码贴的比较详细,希望可以帮到你们

  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值