Appearance
列筛选
为列配置 filters 与 filterMethod,在表头进行单选或多选筛选。
这是列筛选的第一种入口(表头快捷筛选)。需要「A 且(B 或 C)」这类复合条件时, 用第二种入口 高级筛选(筛选管理器),两者可同时使用,结果取交集。
使用的 API
ts
type Column = {
key: string; // 列标识(必填)
title: string; // 列标题(必填)
width: number; // 列宽(必填)
filters: Array<{label, value, checked?}>; // 筛选选项
filterMultiple: boolean; // 是否多选筛选
filterMethod: (value, row) => boolean; // 自定义筛选方法
}
type Options = {
list: T[]; // 数据列表
itemKey: string; // 行唯一标识字段名
estimatedSize: number; // 行预估高度(px)
buffer: number; // 缓冲区行数
border: boolean; // 是否显示边框
}示例
微应用尚未挂载。
源码
点击查看源码
ts
import { faker } from '@faker-js/faker';
import {
VirtTable,
} from '@virt-table/vanilla';
import {
vtColumnFilter,
} from '@virt-table/vanilla/plugins';
export function bootstrapTableFilter(root: HTMLElement): () => void {
const departments = ['工程部', '设计部', '市场部', '财务部', '人事部'];
const levels = ['P5', 'P6', 'P7', 'P8'];
const cities = ['北京', '上海', '杭州', '深圳'];
const list = Array.from({ length: 500 }, (_, i) => ({
id: i,
name: faker.person.fullName(),
department: departments[i % departments.length],
level: levels[i % levels.length],
city: cities[i % cities.length],
score: Math.floor(Math.random() * 100),
}));
const columns = [
{ key: 'name', title: '姓名', width: 180 },
{
key: 'department',
title: '部门',
width: 140,
filters: departments.map((d) => ({ label: d, value: d })),
filterMultiple: true,
},
{
key: 'level',
title: '级别',
width: 100,
filters: levels.map((l) => ({ label: l, value: l })),
filterMultiple: false,
},
{
key: 'city',
title: '城市',
width: 120,
filters: cities.map((c) => ({ label: c, value: c })),
},
{
key: 'score',
title: '分数',
width: 120,
filters: [
{ label: '≥ 80 优秀', value: 80 },
{ label: '≥ 60 及格', value: 60 },
{ label: '< 60 不及格', value: -1 },
],
filterMultiple: false,
filterMethod: (filterValue: number, row: { score: number }) => {
if (filterValue === -1) return row.score < 60;
return row.score >= filterValue;
},
},
];
root.innerHTML = `
<div class="virt-table-controls">
<button class="virt-table-btn" id="btnClearFilter">清除全部筛选</button>
</div>
<div id="status" class="status-text"></div>
<div style="width:800px;height:600px;" class="demo-container" id="tableContainer"></div>
`;
const container = root.querySelector('#tableContainer') as HTMLElement;
const status = root.querySelector('#status') as HTMLElement;
const listeners: (() => void)[] = [];
const setStatus = (text: string) => {
status.textContent = text;
};
const table = new VirtTable(container, {
plugins: [vtColumnFilter()],
list,
columns,
itemKey: 'id',
estimatedSize: 40,
buffer: 4,
border: true,
onFilterChange: (filters) => {
const keys = Object.keys(filters);
if (keys.length === 0) {
setStatus(`列筛选:${list.length} 行(无筛选)`);
} else {
const desc = keys.map((k) => `${k}: ${filters[k].join(',')}`).join(';');
const renderTotal = (table.core.state as any).renderTotal ?? list.length;
setStatus(`筛选条件 ${desc},结果 ${renderTotal} 行`);
}
},
});
setStatus(`列筛选:${list.length} 行(点击表头筛选图标)`);
const btnClearFilter = root.querySelector('#btnClearFilter')!;
const onClearFilter = () => {
table.clearAllFilters();
setStatus(`列筛选:${list.length} 行(已清除全部筛选)`);
};
btnClearFilter.addEventListener('click', onClearFilter);
listeners.push(() => btnClearFilter.removeEventListener('click', onClearFilter));
return () => {
table.destroy();
listeners.forEach((off) => off());
root.innerHTML = '';
};
}