模糊筛选指南

示例

想要直接跳到实现部分吗?请查看以下示例:

API

筛选器 API

模糊筛选指南

模糊筛选是一种允许您根据近似匹配筛选数据的技术。当您想要搜索与给定值相似而不是完全匹配的数据时,这非常有用。

您可以通过定义自定义筛选函数来实现客户端模糊筛选。此函数应接收行、columnId 和筛选值,并返回一个布尔值,指示该行是否应包含在筛选后的数据中。

模糊筛选主要用于全局筛选,但您也可以将其应用于单个列。我们将讨论如何为这两种情况实现模糊筛选。

注意: 您需要安装 @tanstack/match-sorter-utils 库才能使用模糊筛选。 TanStack Match Sorter Utils 是 Kent C. Dodds 的 match-sorter 的一个分支。它被分支出来是为了更好地与 TanStack Table 的逐行筛选方法配合使用。

使用 match-sorter 库是可选的,但 TanStack Match Sorter Utils 库提供了一种很好的方法,既可以进行模糊筛选,也可以根据其返回的排名信息进行排序,以便可以按与搜索查询最接近的匹配项对行进行排序。

定义自定义模糊筛选函数

以下是自定义模糊筛选函数的示例:

typescript
import { rankItem } from '@tanstack/match-sorter-utils';
import { FilterFn } from '@tanstack/table';

const fuzzyFilter: FilterFn<any> = (row, columnId, value, addMeta) => {
  // 对项目进行排名
  const itemRank = rankItem(row.getValue(columnId), value)

  // 存储 itemRank 信息
  addMeta({ itemRank })

  // 返回项目是否应被筛选进/出
  return itemRank.passed
}
import { rankItem } from '@tanstack/match-sorter-utils';
import { FilterFn } from '@tanstack/table';

const fuzzyFilter: FilterFn<any> = (row, columnId, value, addMeta) => {
  // 对项目进行排名
  const itemRank = rankItem(row.getValue(columnId), value)

  // 存储 itemRank 信息
  addMeta({ itemRank })

  // 返回项目是否应被筛选进/出
  return itemRank.passed
}

在此函数中,我们使用 @tanstack/match-sorter-utils 库中的 rankItem 函数对项目进行排名。然后,我们将排名信息存储在行的元数据中,并返回项目是否通过排名标准。

将模糊筛选与全局筛选结合使用

要将模糊筛选与全局筛选结合使用,您可以在表格实例的 globalFilterFn 选项中指定模糊筛选函数:

typescript
const table = useReactTable({ // 或您的框架的等效函数
    columns,
    data,
    filterFns: {
      fuzzy: fuzzyFilter, //定义为可在列定义中使用的筛选函数
    },
    globalFilterFn: 'fuzzy', //将模糊筛选应用于全局筛选(模糊筛选最常见的用例)
    getCoreRowModel: getCoreRowModel(),
    getFilteredRowModel: getFilteredRowModel(), //客户端筛选
    getSortedRowModel: getSortedRowModel(), //如果您也想使用排序,则需要客户端排序。
})
const table = useReactTable({ // 或您的框架的等效函数
    columns,
    data,
    filterFns: {
      fuzzy: fuzzyFilter, //定义为可在列定义中使用的筛选函数
    },
    globalFilterFn: 'fuzzy', //将模糊筛选应用于全局筛选(模糊筛选最常见的用例)
    getCoreRowModel: getCoreRowModel(),
    getFilteredRowModel: getFilteredRowModel(), //客户端筛选
    getSortedRowModel: getSortedRowModel(), //如果您也想使用排序,则需要客户端排序。
})

将模糊筛选与列筛选结合使用

要将模糊筛选与列筛选结合使用,您应首先在表格实例的 filterFns 选项中定义模糊筛选函数。然后,您可以在列定义的 filterFn 选项中指定模糊筛选函数:

typescript
const column = [
  {
    accessorFn: row => `${row.firstName} ${row.lastName}`,
    id: 'fullName',
    header: 'Full Name',
    cell: info => info.getValue(),
    filterFn: 'fuzzy', //使用我们的自定义模糊筛选函数
  },
  // 其他列...
];
const column = [
  {
    accessorFn: row => `${row.firstName} ${row.lastName}`,
    id: 'fullName',
    header: 'Full Name',
    cell: info => info.getValue(),
    filterFn: 'fuzzy', //使用我们的自定义模糊筛选函数
  },
  // 其他列...
];

在此示例中,我们将模糊筛选应用于一个组合了数据的 firstName 和 lastName 字段的列。

使用模糊筛选进行排序

将模糊筛选与列筛选结合使用时,您可能还希望根据排名信息对数据进行排序。您可以通过定义自定义排序函数来实现此目的:

typescript
import { compareItems } from '@tanstack/match-sorter-utils'
import { sortingFns } from '@tanstack/table'

const fuzzySort: SortingFn<any> = (rowA, rowB, columnId) => {
  let dir = 0

  // 仅当列具有排名信息时才按排名排序
  if (rowA.columnFiltersMeta[columnId]) {
    dir = compareItems(
      rowA.columnFiltersMeta[columnId]?.itemRank!,
      rowB.columnFiltersMeta[columnId]?.itemRank!
    )
  }

  // 为项目排名相等时提供字母数字后备
  return dir === 0 ? sortingFns.alphanumeric(rowA, rowB, columnId) : dir
}
import { compareItems } from '@tanstack/match-sorter-utils'
import { sortingFns } from '@tanstack/table'

const fuzzySort: SortingFn<any> = (rowA, rowB, columnId) => {
  let dir = 0

  // 仅当列具有排名信息时才按排名排序
  if (rowA.columnFiltersMeta[columnId]) {
    dir = compareItems(
      rowA.columnFiltersMeta[columnId]?.itemRank!,
      rowB.columnFiltersMeta[columnId]?.itemRank!
    )
  }

  // 为项目排名相等时提供字母数字后备
  return dir === 0 ? sortingFns.alphanumeric(rowA, rowB, columnId) : dir
}

在此函数中,我们比较两行的排名信息。如果排名相等,我们将回退到字母数字排序。

然后,您可以在列定义的 sortFn 选项中指定此排序函数:

typescript
{
  accessorFn: row => `${row.firstName} ${row.lastName}`,
  id: 'fullName',
  header: 'Full Name',
  cell: info => info.getValue(),
  filterFn: 'fuzzy', //使用我们的自定义模糊筛选函数
  sortFn: 'fuzzySort', //使用我们的自定义模糊排序函数
}
{
  accessorFn: row => `${row.firstName} ${row.lastName}`,
  id: 'fullName',
  header: 'Full Name',
  cell: info => info.getValue(),
  filterFn: 'fuzzy', //使用我们的自定义模糊筛选函数
  sortFn: 'fuzzySort', //使用我们的自定义模糊排序函数
}