ARTICLE DETAIL

资讯详情

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

Filament 自定义表格列(Custom Columns)完整实战指南:创建可复用列类与 Blade 视图

Filament 自定义表格列(Custom Columns)完整实战指南:创建可复用列类与 Blade 视图 Filament 自定义表格列Custom Columns完整实战指南创建可复用列类与 Blade 视图【免费下载链接】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 中如何创建属于自己的自定义表格列Custom Column从make:filament-table-column命令生成列类与 Blade 视图到在视图中访问列状态、当前行 Eloquent 记录、Livewire 组件实例与列实例再到为列添加可配置方法并支持 Filament 的工具注入Utility Injection机制。读完本文你将能够把任意复杂的展示逻辑封装成一个可跨项目复用、甚至可作为插件发布给社区的表格列组件。什么是自定义列为什么需要它Filament 内置了丰富的表格列例如 Text 列、Icon 列、Image 列、Color 列以及 Select 列、Toggle 列、Text input 列、Checkbox 列 等可编辑列详见 列总览。但真实业务中总有一些展示需求是内置列无法直接覆盖的——比如在表格里渲染一个音频播放器、一段自定义可视化图表或者带复杂交互的富媒体卡片。此时你可以创建自己的自定义列类column class和视图view。这样做有三大好处可复用同一套列可以在项目的多个表格、多个资源中反复使用可配置像内置列一样通过链式方法如-speed(0.5)为不同场景传入不同配置可分发可以打包成插件发布给 Filament 社区供其他开发者安装使用。快速上手生成自定义列Filament 提供了专门的 Artisan 命令来生成自定义列命令位于 packages/tables/src/Commands/MakeColumnCommand.phpphp artisan make:filament-table-column AudioPlayerColumn该命令会生成两个文件。首先是组件类默认放置在app/Filament/Tables/Columns/目录下use Filament\Tables\Columns\Column; class AudioPlayerColumn extends Column { protected string $view filament.tables.columns.audio-player-column; }其次是一个 Blade 视图文件位于resources/views/filament/tables/columns/audio-player-column.blade.php。默认视图内容来自 ColumnView.stub初始状态大致如下div {{ $getExtraAttributeBag() }} {{ $getState() }} /div即默认渲染一个携带extraAttributes()属性包attribute bag的div内部输出列状态。命令的别名与可用选项从源码 MakeColumnCommand.php 可以看出该命令注册了多个别名含义相同filament:columnfilament:table-columnmake:table-column命令还支持两个选项见 getOptions()选项简写作用--embedded-view-E不生成独立的 Blade 视图文件而是把 HTML 直接内嵌进列类通过toEmbeddedHtml()方法返回字符串。好处是性能更好缺点是无法使用 Blade 语法--force-F当目标文件已存在时强制覆盖其内容嵌入式视图模式Embedded View如果选择--embedded-view从 ColumnClassGenerator.php 的源码可以看到生成的类会实现Filament\Support\Components\Contracts\HasEmbeddedView契约并生成一个toEmbeddedHtml()方法例如public function toEmbeddedHtml(): string { ob_start(); ? div ? e($this-getState()) ? /div ?php return ob_get_clean(); }由于嵌入式模式不走 Blade 引擎列类中定义的公共方法不会自动变成视图中可调用的函数因此该模式更适合简单的、静态的 HTML 输出场景需要复杂逻辑时建议使用独立的 Blade 视图文件。关键认知表格列不是 Livewire 组件使用自定义列前必须先建立正确的心理模型Filament 表格列并不是 Livewire 组件。这意味着在列类上定义的公共属性和公共方法并不会像 Livewire 组件那样自动暴露给 Blade 视图。列本质上是一个数据描述对象由Column::make()构造见 Column.php它负责描述这一列应该如何渲染而真正与前端交互的是包裹它的那个表格 Livewire 组件。那么在 Blade 视图中到底能拿到什么下面逐一展开。在 Blade 视图中访问列数据与上下文访问列的状态$getState()列的状态state就是该列要展示的核心数据。当列被挂载到资源表格时状态会自动取自当前行记录上对应属性的值详见 列总览中的 state 说明。在视图里用$getState()函数访问div {{ $getState() }} /div$getState()返回的是mixed你可以对它做任何 PHP 处理再输出为任何你想要的 HTML 结构——这正是自定义列的核心能力内置列替你排版自定义列让你完全掌控排版。访问当前行的 Eloquent 记录$record很多时候只拿到列状态还不够你可能需要读取当前记录上的其他字段。视图中的$record变量就是当前表格行的 Eloquent 模型实例由 Column.php 的 getExtraViewData() 注入到视图数据中div {{ $record-name }} /div这样你就能基于整条记录拼装复杂的展示内容比如根据$record-cover_url渲染封面图、根据$record-duration计算播放时长等。访问当前 Livewire 组件实例$this在列视图的 Blade 模板中$this指向当前承载表格的 Livewire 组件实例。这意味着你可以按需判断当前所处的上下文甚至调用组件上的方法、派发事件php use Filament\Resources\Users\RelationManagers\ConferencesRelationManager; endphp div if ($this instanceof ConferencesRelationManager) You are editing the conferences of a user. endif /div这个能力在开发上下文敏感的列时非常实用——同一个列在资源页面与在关系管理器Relation Manager中渲染时可以表现出不同的行为。访问当前列实例$column$column变量指向当前列本身的对象实例。你可以借此调用列上的公共方法读取那些没有以独立变量形式暴露给视图的信息div if ($column-isLabelHidden()) This is a new conference. endif /div例如内置列提供的isLabelHidden()、getAlignment()、getName()等方法都可以在这里使用。这也是实现配置方法的基础——见下一节。为自定义列添加配置方法一个优秀的自定义列应当像内置列一样支持链式配置。实现方式是在列类中定义一个公共方法接收配置值存入受保护属性再定义一个 getter 方法取出。以文档中的AudioPlayerColumn为例use Filament\Tables\Columns\Column; class AudioPlayerColumn extends Column { protected string $view filament.tables.columns.audio-player-column; protected ?float $speed null; public function speed(?float $speed): static { $this-speed $speed; return $this; } public function getSpeed(): ?float { return $this-speed; } }注意两点约定setter 方法返回static这样才能支持链式调用AudioPlayerColumn::make(recording)-speed(0.5)getter 方法命名为getXxx()这决定了它在 Blade 视图中的调用方式。在 Blade 视图中列类上的任何公共方法都会以同名变量函数的形式暴露出来。也就是说getSpeed()在视图中可直接以$getSpeed()调用div {{ $getSpeed() }} /div使用列时通过公共方法传入配置值即可use App\Filament\Tables\Columns\AudioPlayerColumn; AudioPlayerColumn::make(recording) -speed(0.5)配置方法与工具注入Utility Injection上面的写法只能接收静态值。Filament 有一个强大的特性叫工具注入允许用户在配置方法里传入闭包Closure闭包的参数会被自动解析并注入各种运行时工具如$record、$state、$livewire等从而让配置值动态计算。要支持工具注入你需要做两件事详见 列总览中的 utility injection 章节在属性与 setter 参数的类型声明中加入Closure在 getter 中把配置值交给$this-evaluate()处理——它会自动执行闭包并注入工具如果传入的是静态值则原样返回。use Closure; use Filament\Tables\Columns\Column; class AudioPlayerColumn extends Column { protected string $view filament.tables.columns.audio-player-column; protected float | Closure | null $speed null; public function speed(float | Closure | null $speed): static { $this-speed $speed; return $this; } public function getSpeed(): ?float { return $this-evaluate($this-speed); } }这样一来用户既可以传静态值也可以传闭包并按需注入工具use App\Filament\Tables\Columns\AudioPlayerColumn; AudioPlayerColumn::make(recording) -speed(fn (Conference $record): float $record-isGlobal() ? 1 : 0.5)上面的例子中$record参数就是被自动注入的——它指向当前行的 Eloquent 记录。evaluate()的底层原理evaluate()的实现位于 packages/support/src/Concerns/EvaluatesClosures.php如果传入值不是Closure直接原样返回如果是闭包则通过反射遍历闭包的所有参数逐一解析依赖优先匹配命名注入、类型注入再回退到组件自身的默认解析逻辑最后用解析出的依赖数组调用闭包。而列组件自身的默认依赖解析逻辑定义在 Column.php 的resolveDefaultClosureDependencyForEvaluationByName()中支持按参数名注入以下工具参数名注入内容$livewire当前 Livewire 组件实例$record当前行的 Eloquent 记录$rowLoop当前表格行的循环对象Laravel Blade 的$loop$state当前列的状态值$table当前表格实例此外通过resolveDefaultClosureDependencyForEvaluationByType()Column.php凡是类型声明为 EloquentModel子类的参数如Conference $record也会按类型自动注入当前记录。这解释了为什么fn (Conference $record)能直接拿到当前行模型。得益于反射机制多个工具可以以任意顺序组合注入也可以混入 Laravel 容器中可解析的依赖如Request使自定义列的配置 API 拥有与内置列完全一致的能力。完整示例打造一个可复用的音频播放器列综合以上所有知识一个完整的AudioPlayerColumn生产级示例大致如下。步骤 1生成骨架php artisan make:filament-table-column AudioPlayerColumn步骤 2编写列类app/Filament/Tables/Columns/AudioPlayerColumn.php?php namespace App\Filament\Tables\Columns; use Closure; use Filament\Tables\Columns\Column; class AudioPlayerColumn extends Column { protected string $view filament.tables.columns.audio-player-column; protected float | Closure | null $speed null; protected bool | Closure $autoplay false; public function speed(float | Closure | null $speed): static { $this-speed $speed; return $this; } public function getSpeed(): ?float { return $this-evaluate($this-speed); } public function autoplay(bool | Closure $autoplay true): static { $this-autoplay $autoplay; return $this; } public function getAutoplay(): bool { return (bool) $this-evaluate($this-autoplay); } }步骤 3编写视图resources/views/filament/tables/columns/audio-player-column.blade.phpdiv audio controls src{{ $getState() }} if ($getAutoplay()) autoplay endif if ($getSpeed()) playbackRate{{ $getSpeed() }} endif /audio if ($record?-title) p classtext-xs text-gray-500{{ $record-title }}/p endif /div步骤 4在表格中使用use App\Filament\Tables\Columns\AudioPlayerColumn; public function table(Table $table): Table { return $table -columns([ AudioPlayerColumn::make(recording_url) -speed(fn (Post $record): float $record-is_premium ? 1 : 0.75) -autoplay(false), // ... ]); }在这个示例中$getState()输出recording_url字段作为音频源$record-title读取当前行的标题作为辅助说明speed()与autoplay()两个配置方法均支持静态值与闭包注入。更多进阶方向列基类能力自定义列继承的Column基类Column.php本身通过大量 trait 提供了对齐、宽度、排序、搜索、隐藏/可见、tooltip、extraAttributes()等能力这些能力会直接继承到你的自定义列上无需重复实现。全局默认配置如果想要所有自定义列默认启用某个行为可在服务提供器的boot()中调用AudioPlayerColumn::configureUsing(...)批量配置参考 列总览的 Global settings 章节再在单列上用-speed(null)等调用覆盖。发布为插件将列类与视图打包进独立的 Composer 包即可作为插件供社区安装列类的公共配置 API 越完善第三方开发者使用起来就越顺畅。测试保障仓库的 tests/src/Tables/Columns/ 目录下为各类内置列编写了完整的测试用例开发自定义列时可参考其写法用 Filament 的表格测试工具验证渲染与交互行为。小结自定义列是 Filament 表格体系中最灵活的扩展点之一。核心要点可归纳为四条用php artisan make:filament-table-column生成列类与视图命令同时提供filament:column、make:table-column等别名以及--embedded-view/--force选项牢记列不是 Livewire 组件视图中的数据来源是$getState()、$record、$this与$column四个入口通过公共 setter 存值 getter 取值的模式为列设计链式配置 API属性与 setter 类型声明Closure并在 getter 中使用$this-evaluate()即可免费获得完整的工具注入能力让配置值随$record、$state、$livewire等上下文动态计算。掌握这四条你就能把任何复杂的单元格展示逻辑沉淀为可复用、可配置、可分发的自定义表格列。【免费下载链接】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),仅供参考
返回列表