编程

Filament v4 Beta 版发布 - 特性一览(1/2)

24 2025-06-18 01:19:00

介绍

Filament v4 Beta 发布,伴随着一系列强大,有用的更新。它变得更快、更容易使用,同时让你在创建应用时拥有更多的控制权。本文将对着重于新特性以及这些更新如何改进你的工作流!

要将你的应用升级至 v4 beta,请阅读升级指南。如果你要安装全新应用,请查看安装指南。

本是介绍的是 Filament 4.x 的特性,其当前版本是 beta 测试版而非稳定版。请注意测试期间仍然可能引入破坏性更新。

稳定版请查看 3.x 文档

概论

性能

Filament 中的渲染和交互性能得到了显著提高,特别是对于大型表格。在内部,许多 Blade 模板已经经过优化,以减少渲染的视图数量。通过利用现有的 PHP 对象来渲染 HTML,而不是引入新文件,Filament v4 减少了需要加载的文件数量,提高了性能。通过将 Tailwind CSS 类组提取到专用类中,然后在 Blade 模板中使用,Blade 视图的大小也得到了减小。这减少了需要渲染的 HTML 量,从而加快了页面加载速度,减小了响应体大小。

Filament v4 现在使用 Tailwind CSS v4

Tailwind CSS v4 是一个大的版本更新,聚焦于性能、灵活性以及符合现代 web 标准。它重新设计了配置系统,改进了自定义方式并提升了编译速度,使得大规模构建自己的定制设计系统变得更加容易。有关最新功能和发行说明,请访问 Tailwind CSS 博客。

Tailwind CSS v4 通过从 rgb 切换到 oklch 来现代化其色彩系统,使用更宽的 P3 色域来生成超越 sRGB 限制的更生动、更准确的色彩。

由于 Filament v4 是在 Tailwind v4 的基础上构建的,因此其主题化系统也采用了oklch。

语义化标题以及动态色彩系统

随着 v4 的更新,你将注意到,你的应用实现了一些辅助功能:

  • 标题级别现在是动态生成的,以保持合适的语义化 HTML 结构并提高可访问性。
  • 现在,调色板可以更准确地从单一基色生成。
  • 文本颜色根据元素的背景颜色动态计算,以确保更易访问的对比度并提高可读性。

身份认证

多因素身份认证

在 Filament v4 中,除了传统的邮箱/密码认证之外,多因素认证(MFA)提供了额外的安全保障。

Filament 支持两个内置 MFA 认证方式:

  • 使用 TOTP 应用进行身份认证,比如 Google Authenticator, Authy 或者 Microsoft Authenticator 应用。
  • 邮箱身份认证,发送一次性验证码到用户邮箱

如果有需要其他身份认证,可以通过注册自定义 MFA provider 来扩展 Filament 的身份认证方式。

Heroicon

Filament 引入了 Heroicon 图标库,因此你可以在无需安装其他插件的情况下使用图标。新增的 Heroicon 枚举类提供了 IDE 自动补全,帮助你快速找到需要的图标,减少记忆负担。

每个图标都有 solid 和 outlined 变体(Heroicon::Star vs. Heroicon::OutlinedStar)。Filament 基于上下文选择合适的大小(16px, 20px 或者 24px。.

使用 FilamentTimezone 设置默认时区

新增的 FilamentTimezone facade 允许你通过 FilamentTimezone::set() 方法为 Filament 设置全局时区,简化了跨组件的默认时区。这将允许你一次性控制多个组件,包括 DateTimePicker、TextColumnTextEntry

"ISO" 格式

现在,在 TextColumnTextEntry 组件中日期和时间支持使用标准 “ISO" 格式进行格式化。

资源

嵌套资源

关联管理器以及关联页面使显示和管理资源中的关联记录变得容易。例如,在 CourseResource 中,你可以使用关联管理器或页面来管理属于 Course 的 Lession。这使你可以使用模态框直接从表中创建和编辑 Lesson。但如果课程(Lesson)更复杂,模态框可能还不够。在这种情况下,你可以使用全页面创建和编辑视图为课程提供自己的资源,这被称为嵌套资源。

资源类组织

资源类现在在它们自己的专用命名空间中生成,让你的代码库更加有序。

代码质量小技巧

对于如何在 v4 中保持 Filament 代码的整洁和可维护性,有一些小技巧:

使用 Schema 类和 Table 类将大型 form()table() 定义分离到各自的文件中。这有助于避免臃肿的方法并提高可读性。

当单个表单输入、表单字段、过滤器或操作变得复杂时,创建专用的组件类。这使每个逻辑都保持专注和可重用。

按类型和目的组织组件,例如将表单输入放在 Schemas/Components 下,将表操作放在 Action 下。.

Create Another 时保留数据

默认情况下,Create 和 Create Another Action 会在提交后清理表单。如果你想保留特定的值,你可以在 Create 页面类中使用 preserveFormDataWhenCreatingAnother() 并只返回你想要保留的值。

当使用 Create Action 时,你可以使用 preserveFormDataWhenCreatingAnother() 方法。

自定义页面内容

在 Filament v4 之前,我们没有一种特别符合人体工程学的方法来定制 Filament 面板中的页面布局。现在,Filament 中的每个页面都有自己的 Schema,它定义了页面结构和内容。

您可以使用 content() 方法覆盖默认页面 Schema 以完全控制布局。

这允许你添加、删除或重新排序 Schema 组件,如表、选项卡和自定义元素。

资源创建页面重定向

现在你可以配置创建资源后的默认重定向行为。
通过面板配置,你可以选择让用户在创建完记录后重定向到首页、视图页面还是编辑页面。

这全局适用于面板内的所有资源。

禁用搜索词拆分

新增 $shouldSplitGlobalSearchTerms 属性允许你禁止全局搜索词拆分成单独的词语,改进大数据集的搜索性能。

关联管理器

自定义内容选项卡

Edit 和 View 页面现在支持主内容选项卡的完全自定义。
通过重写 getContentTabComponent() 方法,你可以使用任何选项卡自定义选项,包括修改标签、图标、深圳添加额外的自定义行为。 ab

在此之前,智能自定义图标,而现在整个选项卡组件都是可配置的。

导航(Navigation)

侧边栏(Sidebar)/顶部导航栏(Topbar)

SidebarTopbar 现在都是 Livewire 组件,允许动态更新。如果你需要刷新它们——比如,在完成设置或者权限修改之后——你可以发送 refresh-sidebarrefres-topbar 浏览器事件以触发重载。

Schemas

Schemas 是 Filament 服务驱动 UI 方式的基础。它让你在 PHP 中使用结构化配置对象创建用户界面,而无需手动编写 HTML 或者 Javascript。这些 schema 定义了你的 UI 的外观和行为,代表组件包括表单字段、信息列表字段、布局组件和基础组件。

每一个 Filament UI 组件 — 无论是表单字段、描述列表还是静态元素,比如文本或者按钮,都是通过 Schema 进行配置的。组件是模块化的、可内嵌的及可宠用的,保持你界面的一致性且使之易于维护。

Schema 是通过 Filament\Schemas\Schema 对象表现出来的,你可以在 components() 方法中将组件数组给它。

查看所有可用组件,请查看 Schemas 文档。

垂直选项卡

选项卡(Tabs)通过将组件分组到单独的区域来帮助组织冗长或复杂的 Schema,减少视觉混乱,使表单更容易导航。

现在,可以通过调用 vertical() 方法切换到垂直选项卡布局。

容器查询

除了基于视口大小的传统断点外,你还可以使用容器查询根据父容器的大小创建响应式布局。

表单

富文本编辑器

富文本编辑器现在使用的是 Tiptap,一个现代、无头及高可扩展的开源编辑器框架。

将内容存储为 HTML 或 JSON

默认情况下,富文本编辑器将内容存储成 HTML 格式。如果你想将内容存储成 JSON,可以使用 json() 方法。

自定义块(Custom blocks)

自定义块(custom blocks)是用户可以拖拽到富文本编辑器的元素,你可以使用 customBlocks() 方法定义用户可以插入到富文本编辑器的自定义块。 

合并标签

合并标签(Merge tags)允许用户将“占位符”(如 {{ name }} 或者 {{ today }})插入到富文本内容中。这些标签会在内容渲染时,被动态值替换,这使得它们在个性化消息或显示日期等方面非常有用。

要启用合并标记,请在配置编辑器时使用 mergeTags() 方法。

用户可以通过键入 {{ 进行搜索,或使用工具栏中的“合并标签”工具插入标签,该工具会打开一个可用标签面板以便于插入。

扩展富文本编辑器

你可以通过创建自定义插件来扩展 Filament 中的富文本编辑器。这些插件允许你添加自己的 TipTap 扩展、工具栏按钮和渲染行为。

滑块(Slider)

滑块组件允许用户通过沿轨迹拖动控制柄来选择一个或多个数值,适合于范围、评级或百分比等输入。

代码编辑器

代码编辑器组件允许用户之间在界面中直接编写和编辑代码。它支持常用语言比如 HTML、CSS、JavaScript、PHPJSON

Table repeaters

Table repeaters 使用定义的 columnsrepeater 项目以表格的布局显示。你可以使用 table() 方法和 TableColumn 对象来配置这些字段,将其映射到 Repeater 的 Schema 中的字段。

每个字段可以自定义为:

  • hiddenHeaderLabel() 隐藏标签,但保留其可访问性。
  • markAsRequired() 添加红星,说明必填字段。
  • wrapHeader() 启用换行以支持长标签。
  • alignment() 设置标题的对齐方式(start、centerend)。
  • width() 定义列字段的固定宽度。

Selecting options from a table in a modal

ModalTableSelect 组件允许用户从显示整个 Filament 表格的模态框中选择记录,尤其适合于有多个纪录需要高级搜索和过滤的关联。

使用 JavaScript 最小化网络请求

hiddenJs() 和 visibleJs()

使用 hidden()visible() 方法并传入一个 PHP 回调,你可以条件性地隐藏或者显示字段。不过,每当响应字段发生变化时,这都会触发完全的 Schema 重载和网络请求,这可能会影响性能。

为提升效率,可以使用 hiddenJs() 或者 visibleJs()。这两个方法在客户端评估 JavaScript 表达式,允许你立即切换字段的可见性而无需重载 Schema。

JsContent

通过传入一个 JsContent 对象使用 JavaScript,你可以动态设置文本内容,比如标签或者 belowContent() 这将允许 label()Textt::make() 这样的方法基于字段值渲染 HTML。

JsContent 中,你可以使用 $state$get 来访问当前字段的状态或者 schema 中的其他字段,启用实时、响应式文本更新而无需服务器交互。

afterStateUpdatedJs()

当 你在 afterStateUpdated() 函数中使用 $set() 设置另一个字段的状态时,它会修改状态,但仍会触发网络请求以重新加载 Schema。

为了避免这种情况,你可以使用 afterStateUpdatedJs(),每当字段值发生变化时,它都会运行一个 JavaScript 表达式。

这种方法完全跳过网络请求,并在客户端立即更新字段。

在这个 JavaScript 上下文中,你可以使用 $state$get()$set() 来高效地与字段状态交互。

将字段合并为一组

FusedGroup 组件允许你将多个字段直观地组合成一个紧凑的分组。它最好与兼容的字段类型一起使用,如文本输入、选择、日期时间选择器和颜色选择器。

添加额外内容到一个字段

字段包含多个插槽,可以在子 schema 中插入内容。插槽可以接受文本、任何 Schema 组件、操作(Action)或操作组(Action Group)——通常是基础组件。

可用插槽包括:

  • aboveLabel(), beforeLabel(), afterLabel(), belowLabel()
  • aboveContent(), beforeContent(), afterContent(), belowContent()
  • aboveErrorMessage(), belowErrorMessage()

局部渲染

默认情况下,在字段上使用 live() 会在其值更改时重新渲染整个 Schema。

Filament 现在提供了更高效的选项:

  • partiallyRenderComponentsAfterStateUpdated() 在状态更新后仅重新渲染的字段。
  • partiallyRenderAfterStateUpdated() 只重新渲染字段本身。
  • skipRenderAfterStateUpdated(): 防止任何重新渲染,仅处理逻辑时有用。

这些工具有助于优化字段交互,特别是当表单只有一部分需要对更改做出反应时。

改进表单字段状态的类型转换

表单字段状态现在会自动转换为正确的数据类型。例如,当使用绑定到枚举的 Select 字段时,即使通过 $state$get() 访问,状态也会返回枚举的实例,而不是原始字符串。这提高了类型一致性,并减少了在逻辑中手动转换的需要。

Infolists

Code entry

Code entry 允许你在信息列表(infolist)中显示高亮代码。它在服务器上使用 Phiki 进行代码高亮标注。

Tables

Tables with custom data

Filament tables are typically backed by Eloquent models, but that's not always ideal. When your data isn't stored in a database — or you want to render external or computed data — you can now use custom data as the data source.

To use custom data, pass an array to the records() method. This lets you render simple datasets without a database, while still supporting features like columns, sorting, searching, pagination, and actions.

You can also fetch data from external APIs. For example, use Laravel's HTTP client to pull data from a REST API and return it as an array in records(). This is useful for integrating third-party services or remote backends.

When working with APIs, make sure to implement proper authentication, error handling, and rate limiting.

Empty relationships with select filters

You can now use the hasEmptyOption() method to include a "None" option that filters for records without a related model. You can customize the label of this option using emptyRelationshipOptionLabel().

Column headers now visible on empty tables

Table headers are now shown even when no records are present, enhancing the user experience — especially when using column-based search and filters.

Bulk actions enhancements

See the bulk actions section of this article.

Actions

Unified actions

Actions are now fully unified across tables, forms, infolists and regular actions.

Instead of having separate Action classes for each context, all actions now use a single Filament\Actions namespace.

Toolbar actions

Tables now support a dedicated toolbar actions area.

You can place both regular actions and bulk actions in the toolbarActions() method.

This is useful for actions like "create", which are not tied to a specific row, or for making bulk actions more visible and accessible in the table’s toolbar.

Bulk actions

Improving bulk action performance

Bulk actions now support the chunkSelectedRecords() method, allowing selected records to be processed in smaller batches instead of loading everything into memory at once — improving performance and reducing memory usage with large datasets.

Authorizing bulk actions

You can now use authorizeIndividualRecords() to check a policy method for each selected record in a bulk action.

Only the records the user is authorized to act on will be included in the $records array.

Bulk action notifications

You can now display a notification after a bulk action completes to inform users of the outcome — especially useful when some records are skipped due to authorization.

  • Use successNotificationTitle() when all records are processed successfully.
  • Use failureNotificationTitle() to show a message when some or all records fail.

Both methods can accept a function to display the number of successful and failed records using $successCount and $failureCount.

Prebuilt bulk actions

Prebuilt bulk actions can now run without fetching and hydrating all selected models, significantly boosting performance for large datasets.

Deselected records

Deselected records are now tracked when using "Select all". This improves performance by minimizing how many record keys need to be stored.

Rate limiting actions

You can now use the rateLimit() method to limit how often an action can be triggered — per user IP, per minute.

Authorization

Authorization messages can now be shown in action tooltips and notifications.

Import action

Importing relationships

BelongsToMany relationships can now be imported via actions.

Export action

Styling XLSX columns

You can now customize the styling of individual cells in XLSX exports using the makeXlsxRow() and makeXlsxHeaderRow() methods in your exporter class.

Customizing the XLSX writer

You can now configure the OpenSpout XLSX writer in your exporter class:

#Tooltips for disabled buttons

You can now display tooltip()s on disabled buttons.

Testing actions

Testing actions in v4 is now simpler and more streamlined. See the testing actions section for full details.

Widgets

Making the chart collapsible

Charts can now be made collapsible by setting the $isCollapsible property to true on the widget class.

Custom filters for chart widgets

Chart widgets now support custom filter schemas using the HasFiltersSchema trait. You can define filters with filtersSchema() using schema components, and access the submitted filter values via the $this->filters property.

Dashboard

Dashboard widgets now support the full responsive grid layout system.

Multi-tenancy

Multi-tenancy now applies global scopes and lifecycle events automatically.

unique and exists validation

Laravel's default unique and exists validation rules bypass Eloquent models, meaning they ignore global scopes like those used in multi-tenancy. This can lead to false validation failures across tenants.

To ensure proper data isolation between tenants, you can use scopedUnique() and scopedExists() methods.

Panel configuration

Inter font now loaded locally

Filament now loads the Inter font locally instead of from a CDN by default. You can change the font using the font() method in the configuration file.

Sub-navigation position

By default, sub-navigation appears at the start of each page. You can override this globally for the entire panel using the subNavigationPosition() method.

Available options are:

  • Start – default position
  • End – renders at the bottom
  • Top – displays as tabs

Strict authorization mode

By default, Filament allows access to a resource if no policy or policy method exists — assuming authorization isn't required.

To enforce stricter security, you can enable strict authorization mode using strictAuthorization(). This will throw an exception if a policy or method is missing, ensuring all access is explicitly defined.

Email change verification

When using the profile() feature with emailChangeVerification(), users must verify their new email address before it becomes active. A verification link is sent to the new email (valid for 60 minutes), and the address won't update in the database until it's clicked. For added security, a cancellation link is also sent to the user's old email to block unauthorized changes.

Error notifications

You can now customize how error messages appear in your Filament panel.

When Laravel's debug mode is off, Filament replaces Livewire's full-screen error modals with flash notifications. You can:

  • Disable this behavior globally using errorNotifications(false).
  • Customize the default error message with registerErrorNotification(title, body).
  • Set custom messages for specific HTTP status codes using the statusCode parameter.
  • Enable or disable error notifications on a per-page basis via the $hasErrorNotifications property.

This gives you full control over the user experience when something goes wrong.

Conclusion

Filament v4 Beta brings a wide range of improvements designed to make your development experience faster, more consistent, and easier to maintain. Since it's still in beta, now is the perfect time to explore the new features and share feedback. If you need a stable version, refer to the 3.x documentation.

To upgrade your app to Filament v4 beta, please read the upgrade guide. To install Filament v4 into a new app, please visit the installation guide.

Special thanks to Dan Harrin for his incredible work on Filament v4!

This article was written by Leandro Ferreira, with contributions from André Domingues and reviewed by Dan Harrin and Alex Six.

 

下一篇