资讯动态

Filament Schemas 布局组件完全指南:Grid 栅格系统、Flex、Fieldset 与容器查询

发布时间:2026/9/10 5:00:57 来源:尧图企业网站定制
Filament Schemas 布局组件完全指南Grid 栅格系统、Flex、Fieldset 与容器查询【免费下载链接】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 的 Schemas 布局体系为核心系统讲解如何利用columns()、columnSpan()、columnStart()、columnOrder()构建响应式多列布局并深入剖析Grid、Flex、Fieldset三个基础布局组件的用法与源码实现。读完本文你将掌握 Filament 布局组件的全部核心 API、基于 Tailwind 断点与容器查询container queries的响应式方案以及延迟加载、间距控制、自定义 HTML 属性等进阶技巧可直接用于表单、Infolist、Panel 页面等场景。布局组件全景Filament 的栅格系统允许你使用任意布局组件创建响应式、多列布局。packages/schemas/docs/02-layouts.md中给出了内置布局组件的完整清单它们都位于Filament\Schemas\Components命名空间GridFlexFieldsetSectionTabsWizardCalloutEmpty state你也可以创建自定义布局组件以按任意方式展示组件。布局组件可无限嵌套子 schema配合表单字段、Infolist 条目与 Prime 组件 组合出任意复杂的界面。栅格系统columns()方法所有布局组件都提供columns()方法支持两种传参方式整数columns(2)表示在lg断点及以上使用 2 列所有更小设备只显示 1 列。数组以断点为键、列数为值例如columns([md 2, xl 4])会在中等设备显示 2 列、超宽设备显示 4 列。更小设备的默认断点为 1 列除非你显式提供default键。断点sm、md、lg、xl、2xl由 Tailwind 定义对应视口宽度依次约为 640px、768px、1024px、1280px、1536px。从源码看columns()定义于 packages/schemas/src/Concerns/HasColumns.php传入整数时会被自动包装为[lg $columns]传入数组时与原配置合并它同时接受Closure运行时通过evaluate()解析动态值。getAllColumns()会基于默认值[default 1, sm null, md null, lg null, xl null, 2xl null]填充未指定的断点。若当前对象是Schema且存在父组件还会继承父组件的列配置见HasColumns.php第 64-66 行。除了静态值columns()也接受函数动态计算列数并可向函数注入各种工具参数如Get、$record、$operation、$livewire、$component等详见 Schema 总览。例如根据当前用户权限动态决定列数use Filament\Schemas\Components\Grid; Grid::make(fn (): array [ lg auth()-user()-isAdmin() ? 4 : 6, ])-schema([ // ... ]);列跨度columnSpan()除了指定布局组件自身有多少列还可以用columnSpan()指定某个组件在父栅格中占据多少列整数columnSpan(2)表示在lg断点及以上占据 2 列更小设备只占 1 列。数组columnSpan([md 2, xl 4])表示中等设备占 2 列、超宽设备占 4 列更小设备默认 1 列除非提供default键。fullcolumnSpan(full)表示在lg断点及以上占满父栅格整行更小设备占 1 列。columnSpanFull()在所有设备上占满父栅格整行与父栅格列数无关。源码位于 packages/support/src/Concerns/CanSpanColumns.php整数跨度会被包装为[default 1, lg $span]columnSpanFull()实际等价于columnSpan([default full])。由于columnSpan()是Filament\Support\Concerns\CanSpanColumnstrait 提供的所有组件而不只是布局组件都天然具备该方法——这正是文档示例中表单字段可以直接调用columnSpan()的原因。列起始columnStart()若希望组件从栅格的指定列开始使用columnStart()整数columnStart(2)表示在lg断点及以上从第 2 列开始更小设备从第 1 列开始。数组columnStart([md 2, xl 4])表示中等设备从第 2 列开始、超宽设备从第 4 列开始更小设备默认第 1 列除非提供default键。例如让文本框始终从栅格中间开始无论栅格有多少列use Filament\Forms\Components\TextInput; use Filament\Schemas\Components\Grid; Grid::make() -columns([ sm 3, xl 6, 2xl 8, ]) -schema([ TextInput::make(name) -columnStart([ sm 2, xl 3, 2xl 4, ]), // ... ])此例中栅格在小屏为 3 列、超宽为 6 列、超超宽为 8 列文本框分别从第 2、3、4 列开始效果上始终位于栅格中点。columnStart()的实现同样位于 CanSpanColumns.php整数会包装为[lg $start]。方法同样接受Closure动态计算。列排序columnOrder()在不改变 HTML 结构中组件顺序的前提下可用columnOrder()控制组件在栅格中的视觉顺序整数columnOrder(2)表示在lg断点及以上按顺序值 2 显示更小设备使用默认顺序除非提供default键。数组columnOrder([md 2, xl 4])分别设置中等、超宽设备上的顺序值。闭包columnOrder(fn () 1)动态计算顺序。use Filament\Forms\Components\TextInput; use Filament\Schemas\Components\Grid; Grid::make() -columns(3) -schema([ TextInput::make(first) -columnOrder(3), // This will appear last TextInput::make(second) -columnOrder(1), // This will appear first TextInput::make(third) -columnOrder(2), // This will appear second ])也可结合断点做响应式排序在不同屏幕尺寸下呈现不同顺序use Filament\Forms\Components\TextInput; use Filament\Schemas\Components\Grid; Grid::make() -columns([ sm 2, lg 3, ]) -schema([ TextInput::make(title) -columnOrder([ default 1, lg 3, ]), TextInput::make(description) -columnOrder([ default 2, lg 1, ]), TextInput::make(category) -columnOrder([ default 3, lg 2, ]), ])此例中小屏顺序为 title、description、category大屏顺序变为 description、category、title。columnOrder()实现在 packages/support/src/Concerns/CanOrderColumns.php整数包装为[lg $order]同样支持闭包动态计算。一个完整的响应式栅格示例由于所有布局组件都支持columns()可以把栅格配置直接写到 Section 等布局组件上在内部再配合columnSpan()、columnOrder()精细控制每个字段use Filament\Forms\Components\TextInput; use Filament\Schemas\Components\Section; Section::make() -columns([ sm 3, xl 6, 2xl 8, ]) -schema([ TextInput::make(name) -columnSpan([ default 1, sm 2, xl 3, 2xl 4, ]) -columnOrder([ default 2, xl 1, ]), TextInput::make(email) -columnSpan([ default 1, xl 2, ]) -columnOrder([ default 1, xl 2, ]), // ... ])行为解读小于sm时每行 1 列sm及以上 3 列xl及以上 6 列2xl及以上 8 列name 字段在sm起占 2 列、xl起占 3 列、2xl起占 4 列email 在xl起占 2 列。排序方面小于xl时 email 在前、name 在后xl及以上则相反。这正是「不改 DOM、纯配置化响应式」的典型用法其中TextInput等文本输入组件作为表单字段天然继承了columnSpan()能力。基础布局组件Grid 组件所有布局组件都支持columns()但Grid是唯一一个显式栅格语法的布局组件无需额外样式直接把列配置传给Grid::make()即可use Filament\Schemas\Components\Grid; Grid::make([ default 1, sm 2, md 3, lg 4, xl 6, 2xl 8, ]) -schema([ // ... ])从 packages/schemas/src/Components/Grid.php 的源码可见Grid::make()的默认列数为2其渲染逻辑toEmbeddedHtml()仅仅输出一个包裹childSchema的div因此没有任何额外的卡片、标题等视觉样式。测试用例 tests/src/Schemas/Components/GridTest.php 也验证了「默认 2 列」「可用整数构造」「可用响应式数组构造」三种行为。Flex 组件Flex基于 CSS Flexbox 实现弹性宽度布局它不使用 Filament 的栅格系统use Filament\Forms\Components\Textarea; use Filament\Forms\Components\TextInput; use Filament\Forms\Components\Toggle; use Filament\Schemas\Components\Section; use Filament\Schemas\Components\Flex; Flex::make([ Section::make([ TextInput::make(title), Textarea::make(content), ]), Section::make([ Toggle::make(is_published), Toggle::make(is_featured), ])-grow(false), ])-from(md)此例中第一个 Section 会grow()吃掉剩余水平空间第二个 Section 保持自身所需宽度形成经典的「弹性宽度侧栏」效果。from()控制切换到水平布局的 Tailwind 断点sm、md、lg、xl、2xl本例在md及以上水平并排更小设备则垂直堆叠。其实现位于 packages/support/src/Concerns/HasFromBreakpoint.phpFlex 通过use HasFromBreakpoint引入。grow()定义于 packages/support/src/Concerns/CanGrow.php默认true可传布尔值或闭包动态控制。grow()和from()同样支持闭包与工具注入。tests/src/Schemas/Components/FlexTest.php 覆盖了alignment()、verticalAlignment()、from()的静态值与闭包写法以及多种渲染场景。Fieldset 组件Fieldset用于把字段分组每个 fieldset 自带标签label、边框默认是两列栅格use Filament\Schemas\Components\Fieldset; Fieldset::make(Label) -columns([ default 1, md 2, xl 3, ]) -schema([ // ... ])「默认两列」可以从源码证实packages/schemas/src/Components/Fieldset.php 的setUp()方法中调用了$this-columns(2)。此外make()的标签参数可以是string | Htmlable | Closure | null支持闭包动态生成。渲染时组件输出原生fieldset/legend结构见Fieldset.php第 68-71 行语义良好。移除 Fieldset 边框用contained(false)去掉 fieldset 的容器边框use Filament\Schemas\Components\Fieldset; Fieldset::make(Label) -contained(false) -schema([ // ... ])该能力来自Filament\Support\Concerns\CanBeContainedtraitFieldset.php第 17 行引入渲染时通过fi-fieldset-not-containedCSS 类控制样式见Fieldset.php第 64 行。控制组件间距紧凑模式dense()dense()将组件间间距缩减 50%创建更紧凑的布局use Filament\Schemas\Components\Fieldset; Fieldset::make(Dense) -dense() -schema([ // ... ])去除间距gap(false)gap(false)完全移除组件间的间距use Filament\Schemas\Components\Fieldset; Fieldset::make(No gap) -gap(false) -schema([ // ... ])两者的底层实现在 packages/schemas/src/Concerns/HasGap.phpdense()/gap()都接受布尔值或闭包hasGap()与isDense()具有继承语义——Schema会查询父组件的设置组件则向容器逐级上溯见第 23-31 行与第 42-51 行。因此在一个 Section 上调用-dense()其内部所有字段的间距都会收紧。使用容器查询Container Queries传统断点基于视口尺寸而容器查询基于父容器的尺寸。当容器大小与视口无关时例如内容区随可折叠侧栏动态伸缩容器查询尤为有用。第一步指定容器。用gridContainer()把元素标记为容器其宽度决定布局use Filament\Schemas\Components\Grid; Grid::make() -gridContainer() -columns([ // ... ]) -schema([ // ... ])gridContainer()定义于 packages/schemas/src/Components/Concerns/CanBeGridContainer.php默认值为false可传闭包条件动态控制。第二步使用容器断点。标记为容器后该元素及其子元素即可用容器断点替代标准断点——例如md表示容器宽度至少 448pxxl表示至少 576pxuse Filament\Schemas\Components\Grid; Grid::make() -gridContainer() -columns([ md 3, xl 4, ]) -schema([ // ... ])容器断点同样可用于columnSpan()、columnStart()、columnOrder()use Filament\Forms\Components\TextInput; use Filament\Schemas\Components\Grid; Grid::make() -gridContainer() -columns([ md 3, xl 4, ]) -schema([ TextInput::make(name) -columnSpan([ md 2, xl 3, ]) -columnOrder([ default 2, xl 1, ]), TextInput::make(email) -columnSpan([ default 1, xl 1, ]) -columnOrder([ default 1, xl 2, ]), // ... ])本例中容器宽度小于xl576px时 email 在前、name 在后宽度达到 576px 后顺序反转。在旧浏览器上支持容器查询容器查询的浏览器支持率不如传统断点。Filament 提供!前缀的回退断点当浏览器不支持容器查询时自动应用回退值。例如栅格列数同时定义容器断点与回退断点use Filament\Schemas\Components\Grid; Grid::make() -gridContainer() -columns([ md 3, xl 4, !md 2, !xl 3, ]) -schema([ // ... ])!回退断点也可用于columnSpan()、columnStart()、columnOrder()use Filament\Forms\Components\TextInput; use Filament\Schemas\Components\Grid; Grid::make() -gridContainer() -columns([ md 3, xl 4, !md 2, !xl 3, ]) -schema([ TextInput::make(name) -columnSpan([ md 2, xl 3, !md 2, !xl 2, ]) -columnOrder([ default 2, xl 1, !xl 1, ]), TextInput::make(email) -columnOrder([ default 1, xl 2, !xl 2, ]), // ... ])回退断点确保不支持容器查询的浏览器也能随视口尺寸响应例如大屏下仍然保持 name 在前、email 在后。延迟加载子 Schema当布局包含渲染代价高昂的组件时可向其schema()传入一个Schema对象并调用deferLoading()。子 schema 初始仅渲染一个加载指示器待其进入视口后才真正加载use Filament\Forms\Components\TextInput; use Filament\Schemas\Components\Group; use Filament\Schemas\Schema; Group::make() -key(customerDetails) -schema( Schema::make() -components([ TextInput::make(name), TextInput::make(email) -email(), ]) -deferLoading(), )本例使用Group它自身没有任何视觉样式其他接受子 schema 的布局组件亦可采用同样写法。每个延迟加载的 schema 必须有唯一 key上例中它继承了带 key 的父组件customerDetails也可以直接在子 schema 上调用key()。更多细节见 Schema 总览如验证错误自动提前加载、隐藏组件内不加载、加载后保持存活等行为。deferLoading()定义于 packages/schemas/src/Schema.php接受布尔值或闭包条件。给布局组件添加额外 HTML 属性通过extraAttributes()向组件最外层 HTML 元素合并额外属性以「属性名 属性值」数组形式传入use Filament\Schemas\Components\Section; Section::make() -extraAttributes([class custom-section-style])实现位于 packages/support/src/Concerns/HasExtraAttributes.php签名默认extraAttributes(array | Closure $attributes, bool $merge false)默认情况下多次调用extraAttributes()会覆盖之前的属性若希望合并而非覆盖传入merge: trueSection::make() -extraAttributes([class a], merge: true) -extraAttributes([data-id 123], merge: true)该方法同样接受闭包支持运行时动态计算与工具参数注入常用于条件化样式、无障碍role/aria-*属性或自定义数据属性。结语与延伸阅读Filament 的布局体系以「所有布局组件支持columns()、所有组件支持columnSpan()」为核心配合断点数组、闭包动态计算与容器查询可在纯 PHP 声明式代码中构建完整、可复用的响应式界面无需手写 CSS 与 JavaScript。相关主题可继续阅读Schema 总览含组件工具注入与延迟加载详解Section 布局组件Tabs 布局组件Wizard 布局组件Callout 布局组件Empty state 布局组件自定义布局组件相关源码HasColumns、HasGap、CanSpanColumns、CanOrderColumns、CanBeGridContainer相关测试GridTest、FlexTest【免费下载链接】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),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价