Skip to content

Filter 过滤器

用于选择/取消选择选项的过滤器芯片组件。与单选框不同,点击已选中的芯片会取消选择。单选模式下,选中后未选中项会折叠隐藏,并显示 × 重置按钮。使用 multiple 属性可启用多选模式。

名称分类说明类型默认值
type? 风格所有过滤项的预设主题颜色'primary' | 'success' | 'warning' | 'danger' | 'info'
size? 尺寸所有过滤项的尺寸'large' | 'small'
color? 颜色所有过滤项的自定义十六进制颜色string
disabled? 状态是否禁用所有过滤项booleanfalse
disabled? 状态是否禁用booleanfalse
multiple? 行为是否启用多选模式,允许同时选中多个过滤项booleanfalse
name? 行为原生 name 属性string
model-value / v-model? 内容绑定值。单选模式下点击已选中项重置为 undefined;多选模式下为数组string | number | (string | number)[]
options? 内容过滤项数组,每项包含 value、label、disabledFilterOptionProps[]
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>