效果

在这里插入图片描述

index.vue

<!--
 * @FileDescription: 下拉选择
 * @Author: 鱼鱼
 * @Date: 2022/02/15
-->
<template>
  <van-dropdown-menu>
    <van-dropdown-item :title="value1">
        <view class="slotBody">
          <template v-for="item, index in itemList" :key="index">
            <view class="lableTitle">{{ item.title }}</view>
            <view class="bodyContent">
              <view v-for="subItem, subIndex in item.lebelList" :key="subIndex" class="Dbody" @click="handleSelect(item, subItem, subIndex)">
                <text :class="{ 'lableText': true, 'isSelect': subItem.isSelect }">{{ subItem.name }}</text>
              </view>
            </view>
          </template>
        </view>
        <van-divider customStyle="margin: 20rpx 0rpx"/>
        <view class="bottmBtn">
          <view class="reset">
            <van-button color="#f5f6fa" block @click="handleReset"><span style="color: #ee5253">重置</span></van-button>
          </view>
          <view class="determine">
            <van-button color="#ee5253" block @click="handleSure">确定</van-button>
          </view>
        </view>
        <view class="lineBtn"></view>
    </van-dropdown-item>
    <van-dropdown-item :title="value2" :options="option2"/>
  </van-dropdown-menu>
</template>
<script setup lang="ts">
import { ref, reactive, defineEmits, getCurrentInstance } from 'vue'
const proxy = getCurrentInstance()?.proxy
import { itemArr } from './index'
const itemList = reactive(itemArr)

let value1 = ref('菜单一')
let value2 = ref('菜单二')
const option2 = [
    { text: '默认排序', value: 'a' },
    { text: '好评排序', value: 'b' },
    { text: '销量排序', value: 'c' },
]
const emit = defineEmits<{
  (event: 'success', res: string): void,
  (event: 'reset', res: string): void
}>()
const handleSure = () => {
  emit('success', '鱼鱼:确定~~~')
  let arr = itemList.map(item => item.select)
  let title = []
  itemList.map(item => {
    item.select.map(subItem => {
      title.push(item.lebelList[subItem].name)
    })
  })
  value1.value = title.length > 0 ? title.join(',') : '菜单一'
  proxy?.selectComponent('.itemSure').toggle(false)
}
const handleReset = () => {
  emit('reset', '鱼鱼:重置~~~')
  itemList.map(item => {
    item.select = []
    item.lebelList.map((subItem, subIndex) => {
      subItem.isSelect = item.default === subIndex
    })
  })
}
const handleSelect = (obj: any, subObj: any, subIndex: number) => {
  // 当前选中和默认选中一致
  // if(obj.default === subIndex) {
  //   if(subObj.isSelect) return
  //   obj.lebelList.map((item, index) => item.isSelect = obj.default === index)
  //   obj.select = []   
  // }
  // // 当前选中和默认不一致且非重复当前选中
  // if(obj.default !== subIndex && !obj.select.includes(subIndex)) {
  //   console.log("~~~~~~~~~~")
  //   obj.lebelList.map((item, index) => {
  //     item.isSelect = index === subIndex
  //   })
  //   obj.select = [subIndex]
  //   return
  // }
  // if(obj.select.length > 0 && subObj.isSelect && obj.select.includes(subIndex)) {
  //   console.log('+++++++++')
  //   obj.lebelList.map((item, index) => {
  //     item.isSelect = obj.default === index
  //   })
  //   obj.select = []
  //   return
  // }
  // 精简代码(单选)
    // const isSelect = (obj) => {
    //   obj.lebelList.map((item, index) => {
    //     item.isSelect = obj.default === index
    //   })
    //   obj.select = []    
    // }

    // const isNotSelect = (obj) => {
    //   obj.lebelList.map((item, index) => {
    //     item.isSelect = index === subIndex
    //   })
    //   obj.select = [subIndex]   
    // }

    // if(subObj.isSelect) {
    //   if(obj.default === subIndex) return
    //   obj.select.includes(subIndex) ? isSelect(obj) : isNotSelect(obj)
    // }else {
    //   obj.default === subIndex ? isSelect(obj) : isNotSelect(obj)
    // }

    const isSelect = (obj) => {
      if(obj.type === 'radio') {
        obj.lebelList.map((item, index) => {
          item.isSelect = obj.default === index
        })
        obj.select = []
      }
      if(obj.type === 'checkBox') {
        if(obj.default === subIndex) {
          obj.lebelList.map((item, index) => {
            item.isSelect = obj.default === index
          })
          obj.select = []
        } else {
          obj.select = obj.select.filter(item => item !== subIndex)
          obj.lebelList.map((item, index) => {
            item.isSelect = obj.select.length === 0 ? obj.default === index : obj.select.includes(index)
          })
        }
      }
    }

    const isNotSelect = (obj) => {
      if(obj.type === 'radio') {
        obj.lebelList.map((item, index) => {
          item.isSelect = index === subIndex
        })
        obj.select = [subIndex]
      }
      if(obj.type === 'checkBox') {
        obj.select.push(subIndex)
        obj.lebelList.map((item, index) => {
          item.isSelect = obj.select.includes(index)
        })        
      }
    }

    if(subObj.isSelect) {
      if(obj.default === subIndex) return
      obj.select.includes(subIndex) ? isSelect(obj) : isNotSelect(obj)
    }else {
      obj.default === subIndex ? isSelect(obj) : isNotSelect(obj)
    }
}
</script>
<style lang="scss" scoped>
.slotBody {
  overflow-x: scroll;
  max-height: 70vh;
}
.lableTitle {
  font-weight: 700;
  color: #00a8ff;
  margin-left: 20rpx;
}
.bodyContent {
  display: flex;
  flex-wrap: wrap;
  padding: 20rpx 0 0 20rpx;
  .Dbody {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 80rpx;
    flex-basis: calc(25% - 20rpx);
    margin: 0 20rpx 20rpx 0;
    font-size: 14px;
    border-radius: 5rpx;
    background-color: #f5f6fa;
    overflow: hidden;
    .lableText {
        width: 80%;
        text-align: center;
        white-space: nowrap; 
        overflow: hidden;
        text-overflow: ellipsis;
    }
    .isSelect {
      color: #ee5253;
    }
  }
}
.bottmBtn {
  display: flex;
}
.reset { 
  width: 30%;
  margin: 0rpx 10rpx 20rpx 30rpx;
}
.determine {
  width: 70%;
  margin: 0rpx 30rpx 20rpx 10rpx;
}
.lineBtn {
  width: 160rpx;
  height: 10rpx;
  border-radius: 10rpx;
  margin: 0rpx auto 18rpx;
  background-color: #f5cd79;
}
</style>

index.js

export const itemArr = [
    {
        title: '海鲜(单选)',
        type: 'radio',
        default: 0,
        select: [],
        lebelList: [
            {
                name: '不限',
                isSelect: true
            },
            {
                name: '帝皇蟹',
                isSelect: false
            },
            {
                name: '乌贼',
                isSelect: false
            },
            {
                name: '波士顿大龙虾',
                isSelect: false
            },
            {
                name: '鱿鱼',
                isSelect: false
            },
            {
                name: '扇贝',
                isSelect: false
            }
        ]
    },
    {
        title: '海鲜(多选)',
        type: 'checkBox',
        default: 0,
        select: [],
        lebelList: [
            {
                name: '不限',
                isSelect: true
            },
            {
                name: '帝皇蟹',
                isSelect: false
            },
            {
                name: '乌贼',
                isSelect: false
            },
            {
                name: '波士顿大龙虾',
                isSelect: false
            },
            {
                name: '鱿鱼',
                isSelect: false
            },
            {
                name: '扇贝',
                isSelect: false
            }
        ]
    }
]
Logo

前往低代码交流专区

更多推荐