筛选增加多选功能

This commit is contained in:
yml2213
2026-07-11 23:21:54 +08:00
parent 0958991847
commit f81842d46e
9 changed files with 165 additions and 65 deletions
@@ -79,7 +79,6 @@ function closePopover() {
:options="publishOptions.insurance_options"
:popover-props="filterPopoverProps('insurance')"
@update:model-value="updateFilter('insurance', $event)"
@close="closePopover"
/>
<StringFilter
@@ -89,7 +88,6 @@ function closePopover() {
:options="publishOptions.level_options"
:popover-props="filterPopoverProps('stamina')"
@update:model-value="updateFilter('stamina', $event)"
@close="closePopover"
/>
<StringFilter
@@ -99,7 +97,6 @@ function closePopover() {
:options="publishOptions.level_options"
:popover-props="filterPopoverProps('load')"
@update:model-value="updateFilter('load', $event)"
@close="closePopover"
/>
<StringFilter
@@ -109,7 +106,6 @@ function closePopover() {
:options="loginMethodOptions"
:popover-props="filterPopoverProps('loginMethod')"
@update:model-value="updateFilter('loginMethod', $event)"
@close="closePopover"
/>
<StringFilter
@@ -120,7 +116,6 @@ function closePopover() {
:popover-props="filterPopoverProps('region')"
:wide="true"
@update:model-value="updateFilter('region', $event)"
@close="closePopover"
/>
<RangeFilter
@@ -197,7 +192,6 @@ function closePopover() {
:options="publishOptions.rank_options"
:popover-props="filterPopoverProps('rank')"
@update:model-value="updateFilter('rank', $event)"
@close="closePopover"
/>
<RangeFilter
@@ -6,30 +6,50 @@ import { computed } from 'vue'
interface Props {
label: string
placeholder: string
modelValue: string
modelValue: string[]
options: string[]
popoverProps: Record<string, any>
wide?: boolean
}
const props = defineProps<Props>()
const props = withDefaults(defineProps<Props>(), {
modelValue: () => [],
})
const emit = defineEmits<{
'update:modelValue': [value: string]
'update:modelValue': [value: string[]]
close: []
}>()
const isActive = computed(() => {
return !!props.modelValue
})
const selectedValues = computed(() => props.modelValue.filter(Boolean))
const isActive = computed(() => selectedValues.value.length > 0)
const displayLabel = computed(() => {
return props.modelValue || props.placeholder
const values = selectedValues.value
if (!values.length) return props.placeholder
if (values.length === 1) return values[0]
if (values.length === 2) return values.join('、')
return `${values[0]} 等${values.length}项`
})
function selectOption(value: string) {
emit('update:modelValue', value)
emit('close')
function isSelected(value: string) {
return selectedValues.value.includes(value)
}
function toggleOption(value: string) {
if (!value) {
emit('update:modelValue', [])
return
}
if (isSelected(value)) {
emit(
'update:modelValue',
selectedValues.value.filter(item => item !== value)
)
return
}
emit('update:modelValue', [...selectedValues.value, value])
}
</script>
@@ -42,16 +62,17 @@ function selectOption(value: string) {
</button>
</template>
<div class="filter-menu">
<button type="button" :class="{ active: !modelValue }" @click="selectOption('')">
{{ placeholder }}
<button type="button" :class="{ active: !selectedValues.length }" @click="toggleOption('')">
全部
</button>
<button
v-for="item in options"
:key="item"
type="button"
:class="{ active: modelValue === item }"
@click="selectOption(item)"
:class="{ active: isSelected(item) }"
@click="toggleOption(item)"
>
<span class="filter-option-check" :class="{ checked: isSelected(item) }" aria-hidden="true" />
{{ item }}
</button>
</div>