Filter 过滤器
用于选择/取消选择选项的过滤器芯片组件。与单选框不同,点击已选中的芯片会取消选择。单选模式下,选中后未选中项会折叠隐藏,并显示 × 重置按钮。使用 multiple 属性可启用多选模式。
| 名称 | 分类 | 说明 | 类型 | 默认值 |
|---|---|---|---|---|
type | 风格 | 所有过滤项的预设主题颜色 | 'primary' | 'success' | 'warning' | 'danger' | 'info' | — |
size | 尺寸 | 所有过滤项的尺寸 | 'large' | 'small' | — |
color | 颜色 | 所有过滤项的自定义十六进制颜色 | string | — |
disabled | 状态 | 是否禁用所有过滤项 | boolean | false |
disabled | 状态 | 是否禁用 | boolean | false |
multiple | 行为 | 是否启用多选模式,允许同时选中多个过滤项 | boolean | false |
name | 行为 | 原生 name 属性 | string | — |
model-value / v-model | 内容 | 绑定值。单选模式下点击已选中项重置为 undefined;多选模式下为数组 | string | number | (string | number)[] | — |
options | 内容 | 过滤项数组,每项包含 value、label、disabled | FilterOptionProps[] | — |
value | 内容 | 过滤项的标识值 | string | number | — |
label | 内容 | 标签文本 | string | — |
change | 事件 | 选中值改变时触发,取消选择时值为 undefined | (value: FilterValueType | FilterValueType[] | undefined) => void | — |
default | 插槽 | 自定义过滤项内容(使用 PxFilterItem) | — | |
default | 插槽 | 自定义标签内容 | — |
基础用法
绑定 v-model 并提供 options。点击芯片选中,再次点击取消选择。
<template>
<div class="demo-filter">
<px-filter v-model="selected" :options="options" />
<p class="demo-filter__result">Selected: {{ selected ?? 'none' }}</p>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const selected = ref<string | number | undefined>('vue');
const options = [
{ value: 'vue', label: 'Vue' },
{ value: 'react', label: 'React' },
{ value: 'angular', label: 'Angular' },
{ value: 'svelte', label: 'Svelte' },
];
</script>
<style scoped>
.demo-filter {
display: flex;
flex-direction: column;
gap: 12px;
}
.demo-filter__result {
font-family: var(--px-font-family);
font-size: 14px;
color: var(--px-text-color-secondary);
}
</style>禁用状态
在组上使用 disabled 禁用所有选项,或在单个选项上使用。
<template>
<div class="demo-filter">
<p class="demo-filter__label">Group disabled:</p>
<px-filter :options="options" disabled />
<p class="demo-filter__label">Individual disabled:</p>
<px-filter v-model="selected" :options="mixedOptions" />
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const selected = ref<string | number | undefined>('a');
const options = [
{ value: 'a', label: 'Alpha' },
{ value: 'b', label: 'Beta' },
{ value: 'c', label: 'Gamma' },
];
const mixedOptions = [
{ value: 'a', label: 'Enabled' },
{ value: 'b', label: 'Disabled', disabled: true },
{ value: 'c', label: 'Enabled' },
];
</script>
<style scoped>
.demo-filter {
display: flex;
flex-direction: column;
gap: 12px;
}
.demo-filter__label {
font-family: var(--px-font-family);
font-size: 14px;
color: var(--px-text-color-secondary);
margin: 0;
}
</style>类型
使用 type 属性来应用预设主题颜色。
<template>
<div class="demo-filter">
<px-filter v-model="v1" :options="options" type="primary" />
<px-filter v-model="v2" :options="options" type="success" />
<px-filter v-model="v3" :options="options" type="warning" />
<px-filter v-model="v4" :options="options" type="danger" />
<px-filter v-model="v5" :options="options" type="info" />
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const options = [
{ value: 'a', label: 'Alpha' },
{ value: 'b', label: 'Beta' },
{ value: 'c', label: 'Gamma' },
];
const v1 = ref<string | number | undefined>('a');
const v2 = ref<string | number | undefined>('a');
const v3 = ref<string | number | undefined>('a');
const v4 = ref<string | number | undefined>('a');
const v5 = ref<string | number | undefined>('a');
</script>
<style scoped>
.demo-filter {
display: flex;
flex-direction: column;
gap: 16px;
}
</style>自定义颜色
使用 color 属性来设置选中状态的自定义十六进制颜色。
<template>
<div class="demo-filter">
<px-filter v-model="v1" :options="options" color="#ff6b6b" />
<px-filter v-model="v2" :options="options" color="#20c997" />
<px-filter v-model="v3" :options="options" color="#845ef7" />
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const options = [
{ value: 'a', label: 'Alpha' },
{ value: 'b', label: 'Beta' },
{ value: 'c', label: 'Gamma' },
];
const v1 = ref<string | number | undefined>('a');
const v2 = ref<string | number | undefined>('a');
const v3 = ref<string | number | undefined>('a');
</script>
<style scoped>
.demo-filter {
display: flex;
flex-direction: column;
gap: 16px;
}
</style>不同尺寸
使用 size 属性来设置过滤器芯片的大小。
<template>
<div class="demo-filter">
<px-filter v-model="v1" :options="options" size="small" />
<px-filter v-model="v2" :options="options" />
<px-filter v-model="v3" :options="options" size="large" />
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const options = [
{ value: 'a', label: 'Small' },
{ value: 'b', label: 'Default' },
{ value: 'c', label: 'Large' },
];
const v1 = ref<string | number | undefined>('a');
const v2 = ref<string | number | undefined>('b');
const v3 = ref<string | number | undefined>('c');
</script>
<style scoped>
.demo-filter {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 16px;
}
</style>多选模式
使用 multiple 属性启用多选模式。可同时选中多个过滤项,点击 × 按钮清除所有选择。
<template>
<div class="demo-filter">
<px-filter v-model="selected" :options="options" multiple />
<p class="demo-filter__result">Selected: {{ selected.length ? selected.join(', ') : 'none' }}</p>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const selected = ref<(string | number)[]>(['vue']);
const options = [
{ value: 'vue', label: 'Vue' },
{ value: 'react', label: 'React' },
{ value: 'angular', label: 'Angular' },
{ value: 'svelte', label: 'Svelte' },
];
</script>
<style scoped>
.demo-filter {
display: flex;
flex-direction: column;
gap: 12px;
}
.demo-filter__result {
font-family: var(--px-font-family);
font-size: 14px;
color: var(--px-text-color-secondary);
}
</style>插槽子组件
使用 PxFilterItem 作为插槽子组件,以更灵活地控制各个选项。
<template>
<div class="demo-filter">
<px-filter v-model="selected" type="primary">
<px-filter-item value="all" label="All" />
<px-filter-item value="photos" label="Photos" />
<px-filter-item value="videos" label="Videos" />
<px-filter-item value="documents" label="Documents" />
</px-filter>
<p class="demo-filter__result">Selected: {{ selected ?? 'none' }}</p>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const selected = ref<string | number | undefined>('all');
</script>
<style scoped>
.demo-filter {
display: flex;
flex-direction: column;
gap: 12px;
}
.demo-filter__result {
font-family: var(--px-font-family);
font-size: 14px;
color: var(--px-text-color-secondary);
}
</style>