Skip to content
全部文档

概览

简介

Filament 可构建由「小部件(widgets)」组成的动态仪表盘。每个小部件是仪表盘上以特定方式展示数据的元素。例如,可展示统计图表表格

带小部件的仪表盘带小部件的仪表盘

创建小部件

可用 make:filament-widget 命令创建小部件:

bash
php artisan make:filament-widget MyWidget

该命令会询问要创建的小部件类型。可选:

  • Custom可从零构建的自定义小部件。
  • Chart展示图表的小部件。
  • Stats overview展示统计的小部件。
  • Table展示表格的小部件。

排序小部件

每个小部件类都有 $sort 属性,可用于调整其相对其他小部件在页面上的顺序:

php
protected static ?int $sort = 2;

自定义仪表盘页面

若要自定义仪表盘类(例如更改小部件列数),请在 app/Filament/Pages/Dashboard.php 创建新文件:

php
<?php

namespace App\Filament\Pages;

use Filament\Pages\Dashboard as BaseDashboard;

class Dashboard extends BaseDashboard
{
    // ...
}

最后,从配置文件中移除原来的 Dashboard 类:

php
use Filament\Panel;

public function panel(Panel $panel): Panel
{
    return $panel
        // ...
        ->discoverPages(in: app_path('Filament/Pages'), for: 'App\\Filament\\Pages')
        ->pages([]);
}

若未在新建仪表盘类所在目录用 discoverPages() 发现页面,应在 pages() 方法中手动注册该类:

php
use App\Filament\Pages\Dashboard;
use Filament\Panel;

public function panel(Panel $panel): Panel
{
    return $panel
        // ...
        ->pages([
            Dashboard::class,
        ]);
}

创建多个仪表盘

若要创建多个仪表盘,可重复上述流程。创建扩展 Dashboard 类的新页面即可按需添加任意数量的仪表盘。

还需为额外仪表盘定义 URL 路径,否则会落在 /

php
protected static string $routePath = 'finance';

也可通过覆盖 $title 属性自定义仪表盘标题:

php
protected static ?string $title = 'Finance dashboard';

向用户展示的主仪表盘是其有权限访问的第一个(由 canAccess() 方法 控制),并按已定义的导航排序。

仪表盘默认排序为 -2。可用 $navigationSort 控制自定义仪表盘的排序:

php
protected static ?int $navigationSort = 15;

自定义小部件网格

可更改用于展示小部件的网格列数。

然后在新的 app/Filament/Pages/Dashboard.php 中覆盖 getColumns() 方法,返回要使用的网格列数:

php
public function getColumns(): int | array
{
    return 2;
}

响应式小部件网格

你可能希望按浏览器响应式 断点 更改小部件网格列数。可用数组指定各断点应使用的列数:

php
public function getColumns(): int | array
{
    return [
        'md' => 4,
        'xl' => 5,
    ];
}

这与响应式小部件宽度搭配效果很好。

自定义小部件宽度

可用 $columnSpan 属性自定义小部件宽度。可用 1 到 12 的数字表示跨越列数,或用 full 占满整页宽度:

php
protected int | string | array $columnSpan = 'full';
响应式小部件宽度

你可能希望按浏览器响应式 断点 更改小部件宽度。可用数组指定各断点应占用的列数:

php
protected int | string | array $columnSpan = [
    'md' => 2,
    'xl' => 3,
];

在使用响应式小部件网格时尤其有用。

自定义小部件列跨度的仪表盘自定义小部件列跨度的仪表盘

按条件隐藏小部件

可覆盖小部件上的静态 canView() 方法,按条件隐藏它们:

php
public static function canView(): bool
{
    return auth()->user()->isAdmin();
}

表格小部件

可轻松向仪表盘添加表格。先用命令创建小部件:

bash
php artisan make:filament-widget LatestOrders --table

随后可通过编辑小部件文件自定义表格

自定义小部件

开始构建 BlogPostsOverview 小部件:

bash
php artisan make:filament-widget BlogPostsOverview

该命令会创建两个文件:Filament 目录下 /Widgets 中的小部件类,以及 Filament 视图目录下 /widgets 中的视图。

该类是 Livewire 组件,因此可使用全部 Livewire 功能。Blade 视图可包含任意 HTML,并可在视图中访问任何公开的 Livewire 属性。也可用 $this 访问 Livewire 组件实例。

筛选小部件数据

可在仪表盘上添加表单,让用户筛选所有小部件展示的数据。筛选更新后,小部件会以新数据重新加载。

然后在新的 app/Filament/Pages/Dashboard.php 中加入 HasFiltersForm trait,并添加 filtersForm() 方法以返回表单组件:

php
use Filament\Forms\Components\DatePicker;
use Filament\Pages\Dashboard as BaseDashboard;
use Filament\Pages\Dashboard\Concerns\HasFiltersForm;
use Filament\Schemas\Components\Section;
use Filament\Schemas\Schema;

class Dashboard extends BaseDashboard
{
    use HasFiltersForm;

    public function filtersForm(Schema $schema): Schema
    {
        return $schema
            ->components([
                Section::make()
                    ->schema([
                        DatePicker::make('startDate'),
                        DatePicker::make('endDate'),
                        // ...
                    ])
                    ->columns(3),
            ]);
    }
}
带筛选表单的仪表盘带筛选表单的仪表盘

需要筛选数据的小部件类应加入 InteractsWithPageFilters trait,以便用 $this->pageFilters 访问筛选表单的原始数据:

php
use App\Models\BlogPost;
use Carbon\CarbonImmutable;
use Filament\Widgets\StatsOverviewWidget;
use Filament\Widgets\Concerns\InteractsWithPageFilters;
use Illuminate\Database\Eloquent\Builder;

class BlogPostsOverview extends StatsOverviewWidget
{
    use InteractsWithPageFilters;

    public function getStats(): array
    {
        $startDate = $this->pageFilters['startDate'] ?? null;
        $endDate = $this->pageFilters['endDate'] ?? null;

        return [
            StatsOverviewWidget\Stat::make(
                label: 'Total posts',
                value: BlogPost::query()
                    ->when($startDate, fn (Builder $query) => $query->whereDate('created_at', '>=', $startDate))
                    ->when($endDate, fn (Builder $query) => $query->whereDate('created_at', '<=', $endDate))
                    ->count(),
            ),
            // ...
        ];
    }
}

$this->pageFilters 数组始终反映当前表单数据。请注意该数据未经验证,因实时可用,且仅应用于查询数据库。使用前必须确保数据有效。本例中在用于查询前会检查是否已设置开始日期。

用操作模态筛选小部件数据

也可将筛选表单换成操作模态,通过点击页头按钮打开。该方式有多项好处:

  • 筛选表单不必始终可见,可将整页高度留给小部件。
  • 筛选在用户点击「Apply」按钮前不会更新小部件,即用户准备好后才重新加载,可在小部件加载成本较高时提升性能。
  • 可对筛选表单做校验,小部件可依赖数据已有效——未通过校验无法提交。取消模态会丢弃用户更改。

要用操作模态代替筛选表单,可改用 HasFiltersAction trait(而非 HasFiltersForm),并在 getHeaderActions() 中将 FilterAction 注册为操作:

php
use Filament\Forms\Components\DatePicker;
use Filament\Pages\Dashboard as BaseDashboard;
use Filament\Pages\Dashboard\Actions\FilterAction;
use Filament\Pages\Dashboard\Concerns\HasFiltersAction;

class Dashboard extends BaseDashboard
{
    use HasFiltersAction;
    
    protected function getHeaderActions(): array
    {
        return [
            FilterAction::make()
                ->schema([
                    DatePicker::make('startDate'),
                    DatePicker::make('endDate'),
                    // ...
                ]),
        ];
    }
}

处理筛选操作的数据与处理页头筛选表单相同,区别是传给小部件前会先校验。仍需使用 InteractsWithPageFilters trait。

带筛选操作模态的仪表盘带筛选操作模态的仪表盘

在用户会话中持久化小部件筛选

默认情况下,已应用的仪表盘筛选会在页面加载之间保存在用户会话中。要禁用,请在仪表盘页面类中覆盖 $persistsFiltersInSession 属性:

php
use Filament\Pages\Dashboard as BaseDashboard;
use Filament\Pages\Dashboard\Concerns\HasFiltersForm;

class Dashboard extends BaseDashboard
{
    use HasFiltersForm;

    protected bool $persistsFiltersInSession = false;
}

也可在仪表盘页面类中覆盖 persistsFiltersInSession() 方法:

php
use Filament\Pages\Dashboard as BaseDashboard;
use Filament\Pages\Dashboard\Concerns\HasFiltersForm;

class Dashboard extends BaseDashboard
{
    use HasFiltersForm;

    public function persistsFiltersInSession(): bool
    {
        return false;
    }
}

禁用默认小部件

默认情况下,仪表盘会显示两个小部件。可通过更新配置中的 widgets() 数组禁用它们:

php
use Filament\Panel;

public function panel(Panel $panel): Panel
{
    return $panel
        // ...
        ->widgets([]);
}