Skip to content
全部文档

概述

简介

表格是 Web 应用中展示记录列表的常见 UI 模式。Filament 提供基于 PHP 的 API 来定义功能丰富的表格,同时也高度可定制。

表格表格

定义表格列

任何表格的基础都是行与列。Filament 使用 Eloquent 获取表格行的数据,而你负责定义该行中使用的列。

Filament 内置了许多列类型,你可以在此查看完整列表。甚至可以创建自己的自定义列类型,按任意方式展示数据。

列以对象数组的形式存放在 $table->columns() 方法中:

php
use Filament\Tables\Columns\IconColumn;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table;

public function table(Table $table): Table
{
    return $table
        ->columns([
            TextColumn::make('title'),
            TextColumn::make('slug'),
            IconColumn::make('is_featured')
                ->boolean(),
        ]);
}
带列的表格带列的表格

本例中表格有 3 列。前两列显示文本——每行的 title 与 slug。第三列显示图标,根据该行是否 featured 显示绿色对勾或红色叉号。

使列可排序与可搜索

你可以通过链式调用方法轻松修改列。例如,可使用 searchable() 方法使列可搜索。此时表格中会出现搜索框,你就能按该列的值筛选行:

php
use Filament\Tables\Columns\TextColumn;

TextColumn::make('title')
    ->searchable()
带可搜索列的表格带可搜索列的表格

你可以使多列可搜索,Filament 能同时在其中任意列中搜索匹配项。

你也可以使用 sortable() 方法使列可排序。这会在列标题上添加排序按钮,点击后将按该列对表格排序:

php
use Filament\Tables\Columns\TextColumn;

TextColumn::make('title')
    ->sortable()
带可排序列的表格带可排序列的表格

你也可以在列中显示属于关联关系的数据。例如,若有一个属于 User 模型(文章作者)的 Post 模型,你可以在表格中显示用户的姓名:

php
use Filament\Tables\Columns\TextColumn;

TextColumn::make('author.name')
带关联列的表格带关联列的表格

此时,Filament 会在 Post 模型上查找 author 关联,然后显示该关联的 name 属性。我们称之为「点记法」(dot notation),你可以用它显示任意关联的任意属性,甚至嵌套关联。Filament 会用这种点记法为你预加载(eager-load)该关联的结果。

有关列关联的更多信息,请参阅关联部分

在现有列旁添加新列

columns() 方法会重新定义表格的全部列,但有时你可能希望向现有配置添加列,而不完全覆盖。当你有应出现在多个表格中的全局列配置时,这尤其有用。

Filament 为此提供了 pushColumns() 方法。与会替换整个列配置的 columns() 不同,pushColumns() 会将新列追加到任何现有列之后。

与服务提供者(如 AppServiceProvider)的 boot() 方法中的全局表格设置结合使用时尤其强大:

php
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table;

Table::configureUsing(function (Table $table) {
    $table
        ->pushColumns([
            TextColumn::make('created_at')
                ->label('Created')
                ->sortable()
                ->toggleable(isToggledHiddenByDefault: true),

            TextColumn::make('updated_at')
                ->label('Updated')
                ->sortable()
                ->toggleable(isToggledHiddenByDefault: true),
        ]);
});

定义表格筛选器

除了使列 searchable(),从而允许用户通过搜索列内容来筛选表格外,你也可以允许用户以其他方式筛选表格行。筛选器可在 $table->filters() 方法中定义:

php
use Filament\Tables\Filters\Filter;
use Filament\Tables\Filters\SelectFilter;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;

public function table(Table $table): Table
{
    return $table
        ->columns([
            // ...
        ])
        ->filters([
            Filter::make('is_featured')
                ->query(fn (Builder $query) => $query->where('is_featured', true)),
            SelectFilter::make('status')
                ->options([
                    'draft' => 'Draft',
                    'reviewing' => 'Reviewing',
                    'published' => 'Published',
                ]),
        ]);
}
带筛选器的表格带筛选器的表格

本例中我们定义了 2 个表格筛选器。表格上角现在会有一个「筛选」图标按钮。点击后会打开包含我们所定义的 2 个筛选器的下拉菜单。

第一个筛选器渲染为复选框。勾选后,表格中仅显示 featured 行;取消勾选则显示所有行。

第二个筛选器渲染为选择下拉框。用户选择某个选项后,仅显示具有该 status 的行;未选择任何选项时显示所有行。

你可以使用任意 schema 组件 来构建筛选器的 UI。例如,你可以创建自定义日期范围筛选器

定义表格操作

Filament 的表格可以使用操作。它们是可添加到任意表格行末尾,甚至表格页眉的按钮。例如,你可能希望在页眉有「创建」新记录的操作,并在每行上有「编辑」和「删除」操作。批量操作可在选中表格记录时执行代码。

php
use App\Models\Post;
use Filament\Actions\Action;
use Filament\Actions\BulkActionGroup;
use Filament\Actions\DeleteBulkAction;

public function table(Table $table): Table
{
    return $table
        ->columns([
            // ...
        ])
        ->recordActions([
            Action::make('feature')
                ->action(function (Post $record) {
                    $record->is_featured = true;
                    $record->save();
                })
                ->hidden(fn (Post $record): bool => $record->is_featured),
            Action::make('unfeature')
                ->action(function (Post $record) {
                    $record->is_featured = false;
                    $record->save();
                })
                ->visible(fn (Post $record): bool => $record->is_featured),
        ])
        ->toolbarActions([
            BulkActionGroup::make([
                DeleteBulkAction::make(),
            ]),
        ]);
}
带操作的表格带操作的表格

本例中我们为表格行定义了 2 个操作。第一个是「feature」操作。点击后会将记录的 is_featured 属性设为 true——这写在 action() 方法中。使用 hidden() 方法,若记录已经 featured,该操作会被隐藏。第二个是「unfeature」操作。点击后会将记录的 is_featured 属性设为 false。使用 visible() 方法,若记录未 featured,该操作会被隐藏。

我们还定义了一个批量操作。定义批量操作后,表格每一行都会有复选框。该批量操作是 Filament 内置的,会删除所有选中的记录。不过,你也可以轻松编写自己的自定义批量操作

打开操作模态框的表格打开操作模态框的表格

操作也可以打开模态框向用户请求确认,并在其中渲染表单以收集额外数据。建议阅读操作文档,了解它们在 Filament 中的广泛能力。

分页

默认情况下,Filament 表格会分页。用户可在每页 5、10、25 和 50 条记录之间选择。若记录数超过所选数量,用户可使用分页按钮在页面间导航。

带默认分页的表格带默认分页的表格

自定义分页选项

你可以通过向 paginated() 方法传入选项,自定义每页记录数选择器的选项:

php
use Filament\Tables\Table;

public function table(Table $table): Table
{
    return $table
        ->paginated([10, 25, 50, 100, 'all']);
}

WARNING

使用非常大的数字和 all 时请注意,大量记录可能导致性能问题。

自定义默认分页页选项

要自定义默认显示的记录数,请使用 defaultPaginationPageOption() 方法:

php
use Filament\Tables\Table;

public function table(Table $table): Table
{
    return $table
        ->defaultPaginationPageOption(25);
}

INFO

请确保默认分页页选项包含在分页选项中。

要添加指向第一页和最后一页的「两端」链接,请使用 extremePaginationLinks() 方法:

php
use Filament\Tables\Table;

public function table(Table $table): Table
{
    return $table
        ->extremePaginationLinks();
}
带两端分页链接的表格带两端分页链接的表格

使用简单分页

你可以使用 paginationMode(PaginationMode::Simple) 方法启用简单分页:

php
use Filament\Tables\Enums\PaginationMode;
use Filament\Tables\Table;

public function table(Table $table): Table
{
    return $table
        ->paginationMode(PaginationMode::Simple);
}
带简单分页的表格带简单分页的表格

使用游标分页

你可以使用 paginationMode(PaginationMode::Cursor) 方法启用游标分页:

php
use Filament\Tables\Enums\PaginationMode;
use Filament\Tables\Table;

public function table(Table $table): Table
{
    return $table
        ->paginationMode(PaginationMode::Cursor);
}
带游标分页的表格带游标分页的表格

防止查询字符串与分页页码冲突

默认情况下,Livewire 将分页状态存储在 URL 查询字符串的 page 参数中。若同一页面有多个表格,一个表格的分页状态可能被另一个表格的状态覆盖。

要修复此问题,你可以定义 $table->queryStringIdentifier(),为该表格返回唯一的查询字符串标识符:

php
use Filament\Tables\Table;

public function table(Table $table): Table
{
    return $table
        ->queryStringIdentifier('users');
}

禁用分页

默认情况下表格会分页。要禁用分页,应使用 $table->paginated(false) 方法:

php
use Filament\Tables\Table;

public function table(Table $table): Table
{
    return $table
        ->paginated(false);
}

记录 URL(可点击的行)

你可以使用 $table->recordUrl() 方法让表格行完全可点击:

php
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Model;

public function table(Table $table): Table
{
    return $table
        ->recordUrl(
            fn (Model $record): string => route('posts.edit', ['record' => $record]),
        );
}

使用 resource 表格时,每行的 URL 通常已经为你设置好,但可以调用此方法覆盖每行的默认 URL。

TIP

你也可以为特定列覆盖 URL,或在点击列时触发操作

你也可以在新标签页中打开 URL:

php
use Filament\Tables\Table;

public function table(Table $table): Table
{
    return $table
        ->openRecordUrlInNewTab();
}

重排序记录

要允许用户在表格中通过拖放重排序记录,可以使用 $table->reorderable() 方法:

php
use Filament\Tables\Table;

public function table(Table $table): Table
{
    return $table
        ->reorderable('sort');
}

本例中的 sort 数据库列将用于存储表格中记录的顺序。每当你用该列对数据库查询排序时,记录会按所定义的顺序返回。若模型使用了批量赋值保护,还需要将 sort 属性添加到 $fillable 数组中。

使表格可重排序后,表格上会出现一个新按钮,用于切换重排序模式。

带可重排序行的表格带可重排序行的表格

reorderable() 方法接受用于存储记录顺序的列名。若你使用 spatie/eloquent-sortable 之类的包,顺序列为 order_column,则可改用该列:

php
use Filament\Tables\Table;

public function table(Table $table): Table
{
    return $table
        ->reorderable('order_column');
}

reorderable() 方法还将布尔条件作为第二个参数,允许你有条件地启用重排序:

php
use Filament\Tables\Table;

public function table(Table $table): Table
{
    return $table
        ->reorderable('sort', auth()->user()->isAdmin());
}

你可以传入 direction 参数为 desc,按降序而非升序重排序记录:

php
use Filament\Tables\Table;

public function table(Table $table): Table
{
    return $table
        ->reorderable('sort', direction: 'desc');
}

在重排序时启用分页

重排序模式下会禁用分页,以便你在页面之间移动记录。重排序时使用分页通常体验不佳,但若希望覆盖此行为,请使用 $table->paginatedWhileReordering()

php
use Filament\Tables\Table;

public function table(Table $table): Table
{
    return $table
        ->paginatedWhileReordering();
}

自定义重排序触发操作

要自定义重排序触发按钮,可以使用 reorderRecordsTriggerAction() 方法,传入返回操作的闭包。所有可用于自定义操作触发按钮的方法都可以使用:

php
use Filament\Actions\Action;
use Filament\Tables\Table;

public function table(Table $table): Table
{
    return $table
        ->reorderRecordsTriggerAction(
            fn (Action $action, bool $isReordering) => $action
                ->button()
                ->label($isReordering ? 'Disable reordering' : 'Enable reordering'),
        );
}
带可重排序行与自定义触发操作的表格带可重排序行与自定义触发操作的表格

在重排序前后运行代码

你可以使用 beforeReordering()afterReordering() 方法在记录重排序之前或之后运行代码。两个方法都接受一个函数,该函数会收到新的记录键 $order 数组:

php
use Filament\Tables\Table;

public function table(Table $table): Table
{
    return $table
        ->reorderable('sort')
        ->beforeReordering(function (array $order): void {
            // Runs before records are reordered in the database.
        })
        ->afterReordering(function (array $order): void {
            // Runs after records are reordered in the database.
        });
}

自定义表格页眉

你可以使用 $table->heading() 方法为表格添加标题:

php
use Filament\Tables\Table;

public function table(Table $table): Table
{
    return $table
        ->heading('Clients')
        ->columns([
            // ...
        ]);

你也可以使用 $table->description() 方法在标题下方添加描述:

php
use Filament\Tables\Table;

public function table(Table $table): Table
{
    return $table
        ->heading('Clients')
        ->description('Manage your clients here.')
        ->columns([
            // ...
        ]);
带标题与描述的表格带标题与描述的表格

你可以将视图传给 $table->header() 方法,以自定义整个页眉 HTML:

php
use Filament\Tables\Table;

public function table(Table $table): Table
{
    return $table
        ->header(view('tables.header', [
            'heading' => 'Clients',
        ]))
        ->columns([
            // ...
        ]);

轮询表格内容

你可以使用 $table->poll() 方法轮询表格内容,使其按设定间隔刷新:

php
use Filament\Tables\Table;

public function table(Table $table): Table
{
    return $table
        ->poll('10s');
}

延迟加载

数据量大的表格可能需要较长时间加载,此时可以使用 deferLoading() 方法异步加载表格数据:

php
use Filament\Tables\Table;

public function table(Table $table): Table
{
    return $table
        ->deferLoading();
}

使用 Laravel Scout 搜索记录

虽然 Filament 不提供与 Laravel Scout 的直接集成,但你可以使用带 whereKey() 子句的 searchUsing() 方法,按 Scout 结果筛选查询:

php
use App\Models\Post;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;

public function table(Table $table): Table
{
    return $table
        ->searchUsing(fn (Builder $query, string $search) => $query->whereKey(Post::search($search)->keys()));

在正常情况下,Scout 内部使用 whereKey()whereIn())方法检索结果,因此使用它没有性能损失。

要显示全局搜索输入框,表格中至少需要有一列是 searchable()。或者,若你已用 Scout 控制哪些列可搜索,也可以直接对整个表格调用 searchable()

php
use Filament\Tables\Table;

public function table(Table $table): Table
{
    return $table
        ->searchable();
}

设置表格行样式

斑马纹表格行

要启用斑马纹表格行,可以使用 striped() 方法:

php
use Filament\Tables\Table;

public function table(Table $table): Table
{
    return $table
        ->striped();
}
带斑马纹行的表格带斑马纹行的表格

自定义行类名

你可能希望根据记录数据有条件地设置行样式。可以通过 $table->recordClasses() 方法指定要应用到行上的 CSS 类字符串或数组来实现:

php
use App\Models\Post;
use Closure;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Model;

public function table(Table $table): Table
{
    return $table
        ->recordClasses(fn (Post $record) => match ($record->status) {
            'draft' => 'draft-post-table-row',
            'reviewing' => 'reviewing-post-table-row',
            'published' => 'published-post-table-row',
            default => null,
        });
}
带自定义行类名的表格带自定义行类名的表格

全局设置

要自定义所有表格使用的默认配置,可以在服务提供者的 boot() 方法中调用静态 configureUsing() 方法。该函数会对每个被创建的表格运行:

php
use Filament\Tables\Enums\FiltersLayout;
use Filament\Tables\Table;

Table::configureUsing(function (Table $table): void {
    $table
        ->reorderableColumns()
        ->filtersLayout(FiltersLayout::AboveContentCollapsible)
        ->paginationPageOptions([10, 25, 50]);
});