ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Filament 仪表盘 Widgets 完全指南:从创建、布局到全局数据过滤的实战手册

Filament 仪表盘 Widgets 完全指南:从创建、布局到全局数据过滤的实战手册 Filament 仪表盘 Widgets 完全指南从创建、布局到全局数据过滤的实战手册【免费下载链接】filamentA powerful open-source UI framework for Laravel • Build and ship apps admin panels fast with Livewire项目地址: https://gitcode.com/GitHub_Trending/fi/filament本篇指南基于 Filament 面板框架的 widgets 模块系统讲解如何在管理后台中构建由组件widget组成的动态仪表盘dashboard。你将掌握make:filament-widget命令的四种组件类型、组件排序与响应式栅格布局、自定义 Dashboard 页面与多仪表盘、基于会话的组件过滤方案表单与 Action 弹窗两种模式以及如何借助源码理解canView()、getColumns()、$columnSpan、$persistsFiltersInSession等关键机制最终组合出可复用的数据可视化首页。Widgets 是什么仪表盘的组成单元Filament 允许你构建由多个widget组成的动态仪表盘。每个 widget 都是仪表盘上的一个元素以特定方式展示数据。例如你可以在同一个页面上同时展示 统计卡stats overview、图表chart 或 表格table。从源码结构看所有 widget 最终都继承自Filament\Widgets\Widget见 packages/widgets/src/Widget.php它本身是一个Livewire 组件并引入了两个关键 traitCanAuthorizeAccess提供canView()静态方法并在组件hydrate每次 Livewire 请求水合时执行abort_unless(static::canView(), 403)见 packages/widgets/src/Concerns/CanAuthorizeAccess.php这是条件隐藏 widget的安全兜底CanBeLazy提供默认开启的懒加载能力。基类中还定义了$columnSpan默认值为1与$sort默认取值为-1见 packages/widgets/src/Widget.php等基础属性这些都将贯穿本文的布局与排序章节。创建 Widgetmake:filament-widget 命令要创建 widget使用make:filament-widget命令php artisan make:filament-widget MyWidget执行后命令会询问你要创建哪种类型的 widget可选类型如下Custom自定义一个从零构建的 widget完全由你自己编写类与 Blade 视图Chart图表展示 图表 的 widgetStats overview统计概览展示 统计数据 的 widgetTable表格展示 表格 的 widget。命令生成的类默认放在app/Filament/Widgets/目录下。创建表格类时还支持--table选项见下文Table widgets一节。组件排序控制仪表盘上的显示顺序每个 widget 类中都包含一个$sort属性用于改变其在页面上的顺序相对于其他 widgetprotected static ?int $sort 2;排序值越小越靠前。基类Widget中的默认排序为-1并通过getSort()方法对外暴露见 packages/widgets/src/Widget.php因此自定义 widget 只要不显式设置$sort就会排在显式设置了较大排序值的组件之前。仪表盘页面本身也有独立的排序机制见下文多个仪表盘一节。自定义 Dashboard 页面如果你需要自定义仪表盘页面类——例如 修改 widget 栅格列数——可以新建app/Filament/Pages/Dashboard.php文件并继承 Filament 内置的仪表盘页面基类?php namespace App\Filament\Pages; use Filament\Pages\Dashboard as BaseDashboard; class Dashboard extends BaseDashboard { // ... }随后需要从 面板配置文件 中移除原始的Dashboard类use Filament\Panel; public function panel(Panel $panel): Panel { return $panel // ... -discoverPages(in: app_path(Filament/Pages), for: App\\Filament\\Pages) -pages([]); }如果你没有在新建仪表盘类所在的目录使用discoverPages()进行页面发现则需要手动在pages()方法中注册该类use App\Filament\Pages\Dashboard; use Filament\Panel; public function panel(Panel $panel): Panel { return $panel // ... -pages([ Dashboard::class, ]); }创建多个仪表盘如需创建多个仪表盘重复上述自定义流程即可。任何继承Dashboard类的新页面都能成为独立仪表盘理论上可以按业务需要创建任意数量。你需要为额外的仪表盘定义 URL 路径否则它将默认位于/protected static string $routePath finance;你也可以通过覆盖$title属性自定义仪表盘的标题protected static ?string $title Finance dashboard;关于哪个仪表盘是用户的主仪表盘用户看到的主仪表盘是他们有权访问的第一个仪表盘访问权限由 canAccess() 方法 控制并按定义的导航排序顺序确定。仪表盘的默认排序值为-2。你可以通过$navigationSort控制自定义仪表盘的排序protected static ?int $navigationSort 15;注意仪表盘的$navigationSort与 widget 的$sort是两个独立的排序体系——前者决定仪表盘页面之间的先后后者决定同一页面内 widget 之间的先后。自定义 Widget 栅格Customizing the widgets grid你可以改变仪表盘用于展示 widget 的栅格列数。首先必须替换原始的 Dashboard 页面。然后在新的app/Filament/Pages/Dashboard.php中覆盖getColumns()方法返回要使用的栅格列数public function getColumns(): int | array { return 2; }响应式 Widget 栅格你可能希望根据浏览器的响应式断点改变 widget 栅格列数。此时使用一个数组包含各断点应使用的列数public function getColumns(): int | array { return [ md 4, xl 5, ]; }这与响应式 widget 宽度搭配使用效果最佳。自定义 Widget 宽度你可以使用$columnSpan属性自定义 widget 的宽度。可使用 1 到 12 之间的数字表示 widget 跨越的列数或使用full让其占满整页宽度protected int | string | array $columnSpan full;注意基类Widget的默认值为1见 packages/widgets/src/Widget.php而StatsOverviewWidget默认使用full占满整行见 packages/widgets/src/StatsOverviewWidget.php——因为统计卡通常希望横贯页面展示。响应式 Widget 宽度你还可以基于浏览器响应式断点改变 widget 宽度使用包含各断点所占列数的数组protected int | string | array $columnSpan [ md 2, xl 3, ];这在配合响应式 widget 栅格时尤其有用。条件隐藏 Widget你可以在 widget 上覆盖静态canView()方法按条件隐藏它public static function canView(): bool { return auth()-user()-isAdmin(); }从实现上看canView()的返回值不仅在渲染阶段用于决定是否展示组件还会在每次 Livewire 请求水合hydrate时被再次校验若返回falseCanAuthorizeAccesstrait 会直接抛出 403见 packages/widgets/src/Concerns/CanAuthorizeAccess.php从而防止用户通过构造请求访问本应隐藏的 widget 数据。Table Widgets你可以轻松地将表格添加到仪表盘。首先使用命令创建 widgetphp artisan make:filament-widget LatestOrders --table之后你可以通过编辑 widget 文件来自定义表格——表格 widget 的所有列、筛选器、操作等配置方式与独立表格页面完全一致只是它作为 Livewire 组件被嵌入仪表盘。自定义 WidgetCustom widgets以构建BlogPostsOverviewwidget 为例php artisan make:filament-widget BlogPostsOverview该命令会创建两个文件一个 widget 类位于 Filament 目录下的/Widgets子目录即app/Filament/Widgets/BlogPostsOverview.php一个视图位于 Filament 视图目录下的/widgets子目录即resources/views/filament/widgets/blog-posts-overview.blade.php。这个类是 Livewire 组件。过滤 Widget 数据你可以在仪表盘上添加一个表单让用户过滤所有 widget上展示的数据。当过滤条件更新时widget 会以新数据重新加载。首先必须替换原始的 Dashboard 页面。然后在新的app/Filament/Pages/Dashboard.php中添加HasFiltersFormtrait并实现filtersForm()方法返回表单组件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), ]); } }在需要用到过滤数据的 widget 类中需要添加InteractsWithPageFilterstrait它将允许你使用$this-pageFilters属性访问过滤表单的原始数据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数组始终反映当前表单数据但这些数据未经过验证——它是实时可用的设计上只用于查询数据库不应被用作其他用途。你必须在查询前自行确保数据有效。上述示例中我们在使用起始日期前先检查了其是否已设置。使用 Action 弹窗过滤 Widget 数据另一种方案是用 Action 弹窗替代常驻过滤表单用户点击页面头部按钮即可打开。这种做法的优势明显过滤表单不总是可见widget 可以使用页面的完整高度过滤条件不会实时更新 widget直到用户点击Apply按钮才生效——这意味着 widget 不会被频繁重载如果 widget 加载成本较高可显著改善性能过滤表单可执行验证widget 可以信赖数据是有效的——在表单通过验证前用户无法提交。取消弹窗会丢弃用户更改。要使用 Action 弹窗而非过滤表单改用HasFiltersActiontrait 替代HasFiltersForm然后在getHeaderActions()中注册FilterAction类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), // ... ]), ]; } }处理来自过滤 Action 的数据与处理过滤头部表单的方式相同唯一区别是数据在传给 widget 之前已经过验证。InteractsWithPageFilterstrait 依然适用。在用户会话中持久化 Widget 过滤条件默认情况下仪表盘应用的过滤条件会在页面加载之间持久化在用户会话中。要禁用此行为在仪表盘页面类中覆盖$persistsFiltersInSession属性use Filament\Pages\Dashboard as BaseDashboard; use Filament\Pages\Dashboard\Concerns\HasFiltersForm; class Dashboard extends BaseDashboard { use HasFiltersForm; protected bool $persistsFiltersInSession false; }或者在仪表盘页面类中覆盖persistsFiltersInSession()方法use Filament\Pages\Dashboard as BaseDashboard; use Filament\Pages\Dashboard\Concerns\HasFiltersForm; class Dashboard extends BaseDashboard { use HasFiltersForm; public function persistsFiltersInSession(): bool { return false; } }两种写法等价前者适合静态开关后者适合需要按运行时条件例如当前用户或环境动态决定的场景。禁用默认 Widget默认情况下仪表盘上会显示两个 widget。可以通过更新面板配置中的widgets()数组来禁用它们use Filament\Panel; public function panel(Panel $panel): Panel { return $panel // ... -widgets([]); }在 docs-assets 示例应用 中可以找到多个真实的 widget 实现示例可作为自定义 widget 的参考范本。延伸阅读与源码索引统计数据概览 widget 的完整用法Stat::make()、description()、chart()、placeholder()、轮询与懒加载等packages/widgets/docs/02-stats-overview.md其底层实现见 packages/widgets/src/StatsOverviewWidget.php 与 packages/widgets/src/StatsOverviewWidget/Stat.php图表 widget 的类型、getData()/getType()/getOptions()与自定义 Chart.js 插件packages/widgets/docs/03-charts.md核心类见 packages/widgets/src/ChartWidget.phpwidget 基类与轮询机制packages/widgets/src/Widget.php 与 packages/widgets/src/Concerns/CanPoll.php默认轮询间隔5s权限控制 traitpackages/widgets/src/Concerns/CanAuthorizeAccess.php。结合以上资料你可以从零搭建一个集统计卡、图表、表格于一体支持响应式布局、全局过滤与按用户权限裁剪的完整业务仪表盘。【免费下载链接】filamentA powerful open-source UI framework for Laravel • Build and ship apps admin panels fast with Livewire项目地址: https://gitcode.com/GitHub_Trending/fi/filament创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表