Skip to content
全部文档

概览

简介

Schema 是 Filament 服务端驱动 UI(Server-Driven UI)方案的基础。它让你用 PHP 配置对象声明式构建用户界面。这些配置对象表示定义 UI 结构与行为的组件,例如表单、表格或列表。无需手写 HTML 或 JavaScript,你通过创建这些 schema 控制服务端渲染的内容,从而简化开发并保证应用一致性。

Filament 广泛使用 Schema 动态渲染 UI 元素。无论是定义表单字段、页面布局还是操作按钮,schema 对象都同时定义组件配置及其与数据的交互方式。本质上,schema 是 Filament UI 的构建块。

Filament 各包提供多种组件。完整列表见 可用组件 一节:

  • [表单字段](/5.x/forms/overview) 接收用户输入,例如文本输入、选择框或复选框,并集成校验。
  • [Infolist 条目](/5.x/infolists/overview) 用于渲染「描述列表」。条目是可展示文本、图标、图片等只读信息的键值 UI 元素。Infolist 的数据可来自任意来源,常见于单条 Eloquent 记录。
  • [布局组件](/5.x/schemas/layouts) 用于组织组件结构,例如网格、选项卡或多步表单向导。
  • [Prime 组件](/5.x/schemas/primes) 是用于渲染独立静态内容的简单组件,例如文本、图片和按钮(操作)。

Schema 作为多个组件的容器,可在其中添加任意组合的组件。组件内部还可嵌套子 schema,支持无限层级嵌套。

Schema 由 Filament\Schemas\Schema 对象表示,可通过 components() 方法向其传入组件数组。

可用组件

用于构建 表单 时,Filament 包含面向不同数据类型的一组字段:

要以标签-值「描述列表」格式展示数据时,Filament 包含 infolist 条目组件:

要将组件排成 布局,Filament 包含布局组件:

要展示任意内容,Filament 包含 prime 组件:

也可向 schema 插入「操作」按钮。它们可运行 PHP 函数,甚至打开模态框。更多信息见 操作文档

关于构建自定义组件以渲染自己的 Blade 视图,详见 自定义组件文档

Schema 示例

例如,你可能想用 schema 构建表单。Schema 的名称通常由定义它的方法名决定(本例中为 form)。Filament 创建 Schema 对象并传给该方法,方法再返回已添加组件的 schema:

php
use Filament\Forms\Components\Checkbox;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Infolists\Components\TextEntry;
use Filament\Schemas\Components\Grid;
use Filament\Schemas\Components\Section;

$schema
    ->components([
        Grid::make(2)
            ->schema([
                Section::make('Details')
                    ->schema([
                        TextInput::make('name'),
                        Select::make('position')
                            ->options([
                                'developer' => 'Developer',
                                'designer' => 'Designer',
                            ]),
                        Checkbox::make('is_admin'),
                    ]),
                Section::make('Auditing')
                    ->schema([
                        TextEntry::make('created_at')
                            ->dateTime(),
                        TextEntry::make('updated_at')
                            ->dateTime(),
                    ]),
            ]),
    ])
Schema 示例Schema 示例

Grid 是布局组件,将多个组件一起渲染在响应式网格中。网格列数在 make() 方法中指定。使用 schema() 方法在网格内嵌套组件。

Section 是另一个布局组件,将多个组件一起渲染在卡片中,顶部带有标题。

TextInputSelectCheckbox 是接收用户输入的表单组件。

TextEntry 是显示只读信息的 infolist 组件。本例中用于显示记录的创建与更新时间戳。dateTime() 方法用于将时间戳格式化为日期和时间。

Schema 对象是组件的容器,现在可以渲染。渲染 schema 会按正确布局渲染其中的所有组件。

组件工具注入

用于配置条目的绝大多数方法都接受函数作为参数,而不是硬编码值:

php
use Filament\Schemas\Components\Grid;
use Filament\Schemas\Components\Section;

Grid::make(fn (): array => [
    'lg' => auth()->user()->isAdmin() ? 4 : 6,
])->schema([
    // ...
])

Section::make()
    ->heading(fn (): string => auth()->user()->isAdmin() ? 'Admin Dashboard' : 'User Dashboard')
    ->schema([
        // ...
    ])

仅此一点就解锁了许多自定义可能。

该包还能将这些函数内部可用的许多工具以参数形式注入。所有接受函数作为参数的自定义方法都可以注入工具。

这些注入的工具要求使用特定的参数名,否则 Filament 不知道该注入什么。

注入另一个组件的状态

也可在回调中使用 $get 参数获取表单字段或 infolist 条目的状态(值):

php
use Filament\Schemas\Components\Utilities\Get;

function (Get $get) {
    $email = $get('email'); // Store the value of the `email` entry in the `$email` variable.
    //...
}

TIP

除非表单字段是 响应式的,否则字段值变化时 schema 不会刷新,只有在下一次会向服务器发起请求的用户交互时才会刷新。若需要响应字段值的变化,应使用 live()

注入当前 Eloquent 记录

可使用 $record 参数获取当前 schema 的 Eloquent 记录:

php
use Illuminate\Database\Eloquent\Model;

function (?Model $record) {
    // ...
}

注入当前操作

若在为面板资源或关联管理器编写 schema,并希望检查 schema 是 createedit 还是 view,请使用 $operation 参数:

php
function (string $operation) {
    // ...
}

INFO

可使用 $schema->operation() 方法手动设置 schema 的操作。

注入当前 Livewire 组件实例

若要访问当前 Livewire 组件实例,请定义 $livewire 参数:

php
use Livewire\Component;

function (Component $livewire) {
    // ...
}

注入当前组件实例

若要访问当前组件实例,请定义 $component 参数:

php
use Filament\Schemas\Components\Component;

function (Component $component) {
    // ...
}

注入多个工具

参数通过反射动态注入,因此可按任意顺序组合多个参数:

php
use Filament\Schemas\Components\Utilities\Get;
use Filament\Schemas\Components\Utilities\Set;
use Livewire\Component as Livewire;

function (Livewire $livewire, Get $get, Set $set) {
    // ...
}

从 Laravel 容器注入依赖

可像往常一样从 Laravel 容器注入任意依赖,并与工具一起使用:

php
use Filament\Schemas\Components\Utilities\Set;
use Illuminate\Http\Request;

function (Request $request, Set $set) {
    // ...
}

延迟加载子 schema

默认情况下,schema 的组件在页面加载时渲染。若子 schema 渲染成本较高,可使用 deferLoading() 方法将其加载推迟到进入视口时:

php
use Filament\Forms\Components\TextInput;
use Filament\Schemas\Components\Section;
use Filament\Schemas\Schema;

Section::make('Customer details')
    ->key('customerDetails')
    ->schema(
        Schema::make()
            ->components([
                TextInput::make('name'),
                TextInput::make('email')
                    ->email(),
            ])
            ->deferLoading(),
    )

延迟的 schema 最初会渲染加载指示器。当加载指示器进入视口时,仅在新请求中渲染该 schema。若 schema 在加载前已有校验错误,会自动加载以便显示校验错误。

若延迟的 schema 位于折叠的 section 或未激活的选项卡等隐藏组件内,则不会加载,直到其父级显现且它进入视口。一旦 schema 已加载,会在 Livewire 组件的生命周期内保持已加载状态。

每个延迟的 schema 都需要唯一的 key。本例中,子 schema 从 section 继承 customerDetails key。也可在子 schema 自身上调用 key()。若同一组件的多个子 schema 都被延迟(例如 section 的内容与页脚 schema),必须在每个额外的 schema 上调用 key(),以免继承相同 key。若延迟的是 repeater 项或 builder 块的 schema,每个项 schema 会从其状态路径自动获得唯一 key:

php
use Filament\Forms\Components\Repeater;
use Filament\Forms\Components\TextInput;
use Filament\Schemas\Schema;

Repeater::make('members')
    ->schema(
        Schema::make()
            ->components([
                TextInput::make('name'),
                TextInput::make('email')
                    ->email(),
            ])
            ->deferLoading(),
    )

也可向 deferLoading() 传入布尔值或函数,以按条件控制。

全局设置

若要全局更改组件的默认行为,可在服务提供者的 boot() 方法中调用静态 configureUsing() 方法,并向其传入用于修改组件的 Closure。例如,若希望所有 section 组件默认使用 2 列,可以这样做:

php
use Filament\Schemas\Components\Section;

Section::configureUsing(function (Section $section): void {
    $section
        ->columns(2);
});

当然,仍可在每个组件上单独覆盖:

php
use Filament\Schemas\Components\Section;

Section::make()
    ->columns(1)

将 Livewire 文件上传限制到 schema 组件

若在 InteractsWithSchemas 之上构建自定义 Livewire 组件,Livewire 的文件上传 RPC 方法默认接受上传到任意属性路径。关于用于锁定该行为的 RestrictsFileUploadsToSchemaComponents trait,见安全文档中的 将 Livewire 文件上传限制到 schema 组件