微信小程序点击同一个增加背景色,再次点击取消背景色

img

img

img


img


一直被卡壳了!
想实现, 点击同一个增加背景色和去除背景色,可以多选
头部变速箱,也是单击选中,双击取消,只能单选
我是用vant组件复选框,一直没能得到很好的办法!只能做到多选的value都是单一,不是组成一个数组。

你现在是卡在不能切换颜色?

可以单写button按钮,然后定义事件,点击改变按钮背景颜色,再次点击的时候首先判断是否已经有背景了,要是有就加深

点击元素后,获取元素中data-select值,赋值给catalogSelect,然后判断二者是否相等,一样则添加class


    <view class="info_choose ">
        <view class="catalog_name">花色</view>

        <view class="catalog_items display-flex-row" >
          <block wx:for="{{catalogs}}">
            <text data-select="{{item.select}}" class="{{item.select == catalogSelect ? 'active':''}} catalog_item" bindtap="chooseCatalog">{{item.catalogName}}</text>
          </block>
        </view>
    </view>

Page({
    data: {

        catalogs:[
          { "catalogName": "卡其卡其",
            "select":1          
          },
          {
            "catalogName": "其卡其卡卡其卡其",
            "select": 2
          },
          {
            "catalogName": "鲤鱼鲤鱼",
            "select": 3
          },
          {
            "catalogName": "神迹神迹卡其卡其",
            "select": 4
          },  

        ],
        catalogSelect:0,//判断是否选中
    },

    chooseCatalog:function(data){
      var that=this;
      that.setData({//把选中值放入判断值
        catalogSelect : data.currentTarget.dataset.select
      })


    }
})


每项的val会有重复的吗,我这里通过绑定父子级的索引组合来判断

img

<view>
  <view wx:for="{{filters}}" wx:key="index">
    <view class="title">{{item.name}}</view>
    <view class="filter-content">
      <view
        wx:for="{{item.children}}"
        wx:for-item="cItem"
        wx:for-index="cIndex"
        wx:key="cIndex"
        class="filter-item {{tools.includes(selected, index +'_'+ cIndex) ? 'on' : ''}}"
        data-serial="{{index}}_{{cIndex}}"
        bindtap="tapFilterItem">
        {{cItem.name}}
      </view>
    </view>
  </view>
</view>

<wxs module="tools">
var includes = function (array, searchElement) {
  return array.indexOf(searchElement) !== -1
}
module.exports = {
  includes: includes
}
</wxs>
Page({
  data: {
    filters: [
      {
        name: '变速箱',
        children: [
          { code: 1, name: '自动挡' },
          { code: 2, name: '手动挡' }
        ]
      }, {
        name: '座位数',
        children: [
          { code: 3, name: '2座' },
          { code: 4, name: '3座' },
          { code: 4, name: '4座' },
          { code: 4, name: '5座' }
        ]
      }
    ],
    selected: []
  },
  tapFilterItem(e) {
    const { serial } = e.currentTarget.dataset
    let { selected } = this.data
    if (selected.includes(serial)) {
      // 存在 取消选中
      selected.some((item, index) => {
        if (item === serial) {
          selected.splice(index, 1)
          return true
        }
      })
    } else {
      // 不存在 选中
      selected.push(serial)
    }
    this.setData({ selected })
  }
})

比较简单点的,就是给每项增加一个选中标志,flag为true表示选中,false就是取消,代码大致如下:

<view class='moreBoxs'>
      <scroll-view class="navContent" scroll-x>
        <view class="classify {{first_names.flag?'addStyleMi':''}}" bindtap="menuClick" wx:for='{{first_names}}' wx:key='{{index}}' wx:for-item="first_names" wx:for-index="index" data-postid='{{first_names.id}}' data-index='{{index}}' data-postname='{{first_names.classname}}'>
          <text>{{first_names.classname}}</text>
        </view>
      </scroll-view>
  </view>



.moreBoxs{
  width: 100%;
  height: 102rpx;
  border-bottom: solid 2rpx #e5e5e5;
  position: fixed;
  top: 0;
  background-color: #ffffff;
  z-index: 500;
}
.navContent{
  width: 100%;
  height: 102rpx;
  white-space: nowrap;
}
.classify {
  height: 102rpx;
  /*width: 8%;*/
  margin-left: 42rpx;
  line-height: 102rpx;
  text-align: center;
  font-size: 28rpx;
display: inline-block;
}
.addStyleMi {
  height: 96rpx;
  border-bottom: solid 6rpx #eb3737;
  font-weight: bold;
  color: #eb3737;
  font-size: 28rpx;
}
/* ---------隐藏滚动条 */
::-webkit-scrollbar {
width: 0;
height: 0;
color: transparent;
}

// index.js
// 获取应用实例
const app = getApp()

Page({
  data: {
    first_names:[
      {
        "id":1,
        "classname":"自动挡",
        "flag":false
        },
      {
        "id":2,
         "classname": "手动挡",
         "flag":false
      },
    ],
  },
  // 事件处理函数
  menuClick: function (e) {
    var that = this;
    var index = e.currentTarget.dataset.index;//获取当前点击的元素下标
    var oSelected ="first_names["+index+"].flag"
    console.log([oSelected]);
    var flag=true;
    var missionArr = this.data.first_names;
    for (let i in missionArr) {
      //遍历列表数据      
      if (i == index) {
        //根据下标找到目标,改变状态  
        if (missionArr[i].flag == true) {
          flag=false;
        }
      }
    }
    that.setData({
      [oSelected]: flag
    })
  },
})


img

1.采用flex布局 兼容性好: 可以直接运行,效果如上图.


<template>
  <view>
    <view>武将谱</view>
    <view class="classifyBigBox">
      <view class="oneClassify flex" :class="{selectActive:selected[item.id]==true}" v-for="(item,i) in classifyList"
        @click="onSelectClassify(item.id)">
        {{item.name}}
      </view>
    </view>
    <view class="tl-flex-center1">
      <view @click="onClear" class="tl-btn-120">重置</view>
      <view @click="onConfirmFiltrate" class="onConfirmFiltrate">确定</view>
    </view>

  </view>
</template>

<script>
  export default {
    data() {
      return {
        classifyList: Array.from({
          length: 10
        }).map((v, index) => {
          return {
            id: index,
            name: `张飞${index}`
          }
        }), //所以分类数组
        selected: {}, //选取的分类 ,用对象更方便存取数据
      }
    },
    methods: {
      //选取分类
      onSelectClassify(id) {
        this.$set(this.selected, id, !this.selected[id]) //动态更新视图数据
      },
      //重置
      onClear() {
        this.selected = {}
      },
      //提交筛选
      onConfirmFiltrate() {
        let select = [] //选择的筛选结果数组
        const {
          classifyList,
          selected
        } = this

        //Object.keys循环遍历对象,如果值为true,就对比所有分类数组,拿到选择的筛选数据
        Object.keys(selected).forEach(key => {
          if (selected[key]) {
            for (let i = 0; i < classifyList.length; i += 1) {
              classifyList[i].id == key ? select.push(classifyList[i]) : ''
            }

          }

        })
            console.log(select ,"选择结果数组-----");
      }
        

    }

  }
</script>

<style>
  .classifyBigBox {
    margin: 47rpx 0;
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    grid-gap: 50rpx;
  }

  .oneClassify {
    display: flex;
    align-items: center;
    padding: 17rpx;
    justify-content: center;
    background: F7F7F7;
    border-radius: 13rpx;
    color: #999;
    border: 2rpx solid #dedede;
  }

  .selectActive {
    background: #2851F3;
    color: #FFFFFF;
  }

  .tl-btn-120{
    width: 180rpx;
    padding: 17rpx;
    background: F7F7F7;
    color: #999;
    border-radius: 13rpx;
    border: 2rpx solid #dedede;
    text-align: center;
  }
  .onConfirmFiltrate{
    width: 180rpx;
    padding: 17rpx;
    background: #2851F3;
    color: #FFFFFF;
    border-radius: 13rpx;
    text-align: center;
    margin-left: 20rpx;
  }
</style>