87 lines
1.7 KiB
Vue
87 lines
1.7 KiB
Vue
<template>
|
|
<view class="filter-bar">
|
|
<view
|
|
class="filter-item"
|
|
v-for="(filter, index) in filters"
|
|
:key="index"
|
|
>
|
|
<picker
|
|
:range="filter.options"
|
|
range-key="label"
|
|
:value="filter.selectedIndex || 0"
|
|
@change="(e) => onFilterChange(index, e)"
|
|
>
|
|
<view class="filter-trigger">
|
|
<text class="filter-label">{{ getCurrentLabel(filter) }}</text>
|
|
<text class="filter-arrow">▼</text>
|
|
</view>
|
|
</picker>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
export default {
|
|
name: 'FilterBar',
|
|
props: {
|
|
/**
|
|
* 筛选项配置数组
|
|
* 每项格式:{ label: '门店', key: 'storeId', options: [{ label: '全部', value: '' }, ...], selectedIndex: 0 }
|
|
*/
|
|
filters: {
|
|
type: Array,
|
|
default: () => []
|
|
}
|
|
},
|
|
emits: ['change'],
|
|
methods: {
|
|
getCurrentLabel(filter) {
|
|
const idx = filter.selectedIndex || 0
|
|
return filter.options[idx]?.label || filter.label
|
|
},
|
|
onFilterChange(filterIndex, e) {
|
|
const selectedIndex = e.detail.value
|
|
const filter = this.filters[filterIndex]
|
|
const selectedOption = filter.options[selectedIndex]
|
|
this.$emit('change', {
|
|
filterIndex,
|
|
key: filter.key,
|
|
value: selectedOption.value,
|
|
selectedIndex
|
|
})
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.filter-bar {
|
|
display: flex;
|
|
gap: 16rpx;
|
|
padding: 16rpx 20rpx;
|
|
background: #fff;
|
|
border-radius: 12rpx;
|
|
margin-bottom: 20rpx;
|
|
}
|
|
.filter-item {
|
|
flex: 1;
|
|
}
|
|
.filter-trigger {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding: 12rpx 16rpx;
|
|
background: #f5f5f5;
|
|
border-radius: 8rpx;
|
|
}
|
|
.filter-label {
|
|
font-size: 24rpx;
|
|
color: #333;
|
|
}
|
|
.filter-arrow {
|
|
font-size: 18rpx;
|
|
color: #999;
|
|
margin-left: 8rpx;
|
|
}
|
|
</style>
|