效果
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) => {
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
}
]
}
]