ARTICLE DETAIL

资讯详情

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

Filament 表格布局完全指南:从移动端堆叠到自定义行布局

Filament 表格布局完全指南:从移动端堆叠到自定义行布局 Filament 表格布局完全指南从移动端堆叠到自定义行布局【免费下载链接】filamentA powerful open-source UI framework for Laravel • Build and ship apps admin panels fast with Livewire项目地址: https://gitcode.com/GitHub_Trending/fi/filamentFilament 的 Tables 包不仅提供了功能完备的数据列与筛选器还内置了一套强大的响应式布局系统让开发者无需编写 HTML/CSS 即可构建在手机、平板与桌面端都表现良好的表格界面。本文基于 packages/tables/docs/05-layout.md 展开结合 tables 包源码完整讲解stackedOnMobile()移动端堆叠、Split/Stack/Grid/Panel/View布局组件、可折叠内容以及contentGrid()记录网格等核心能力读完你将能够为任意列表页设计出可精细控制、适配各断点的响应式行布局。传统表格布局的困境传统 HTML 表格在响应式方面是出了名的难处理。在移动端面对横向超长的内容通常只有两种做法允许用户横向滚动以查看更多的表格内容在较小设备上隐藏次要列。Filament 对这两种方案都提供了原生支持表格在内容溢出时会自动横向滚动同时你也可以基于浏览器的响应式 Tailwind 断点sm/md/lg/xl/2xl来决定列的显示与隐藏使用visibleFrom()或hiddenFrom()方法use Filament\Tables\Columns\TextColumn; TextColumn::make(slug) -visibleFrom(md)这种做法固然可行但存在一个明显的问题——在移动端用户不滚动就很难在同一行中看到足够多的信息。Filament 为解决这个问题提供了两套方案简单堆叠Simple stacking使用stackedOnMobile()在移动端自动将所有单元格垂直堆叠且完全不需要改动你的列定义自定义布局Custom layouts使用Split、Stack等布局组件精确控制内容在每个断点下的呈现方式。移动端堆叠表格单元格stackedOnMobile()让表格响应式的最简方式是在表格上调用stackedOnMobile()。它会自动把传统的横向表格布局在移动端转换为垂直的卡片式布局而在大屏上保持标准表格外观use Filament\Tables\Columns\TextColumn; use Filament\Tables\Table; public function table(Table $table): Table { return $table -columns([ TextColumn::make(name) -searchable() -sortable(), TextColumn::make(email), TextColumn::make(phone), TextColumn::make(job), ]) -stackedOnMobile(); }在移动端每一行会以卡片的形式展示列标签显示在其值的上方。如果存在可排序的列移动端表格顶部会出现一个排序下拉框用户无需传统的表头行即可排序批量选择同样受支持复选框会出现在表头区域。从源码看该方法定义于 CanBeStackedOnMobile.php 中stackedOnMobile()接收一个布尔值或闭包内部存储在isStackedOnMobile属性中最终由isStackedOnMobile()求值因此你甚至可以写成-stackedOnMobile(fn () auth()-user()-isMobile())这类条件逻辑。这种方式适合需要快速获得响应式效果、且不想重构列定义的场景。但如果布局较复杂、或需要对不同断点下的内容呈现做精细控制则推荐使用下面介绍的布局组件。自定义列布局Filament 允许你完全不接触 HTML 或 CSS就构建出响应式的类表格界面。这些布局组件可以精确决定每一行中的内容出现在哪里、以及每个响应式断点下的表现。Split让列在移动端堆叠先介绍第一个组件——Splituse Filament\Support\Enums\FontWeight; use Filament\Tables\Columns\ImageColumn; use Filament\Tables\Columns\Layout\Split; use Filament\Tables\Columns\TextColumn; Split::make([ ImageColumn::make(avatar) -circular(), TextColumn::make(name) -weight(FontWeight::Bold) -searchable() -sortable(), TextColumn::make(email), ])Split组件用于包裹一组列让它们可以在移动端堆叠显示。默认情况下Split 内的列会一直并排展示。你也可以通过from()指定一个响应式断点让并排行为从该断点才开始在此之前列会上下堆叠use Filament\Support\Enums\FontWeight; use Filament\Tables\Columns\ImageColumn; use Filament\Tables\Columns\Layout\Split; use Filament\Tables\Columns\TextColumn; Split::make([ ImageColumn::make(avatar) -circular(), TextColumn::make(name) -weight(FontWeight::Bold) -searchable() -sortable(), TextColumn::make(email), ])-from(md)在这个示例中列只在md断点及以上的设备上并排显示小于md时全部垂直堆叠。from()由 HasFromBreakpoint.php 提供底层渲染时会在容器上添加{breakpoint}:fi-ta-split这样的 Tailwind 类由 CSS 决定对应断点下的布局行为见 Split.php。阻止列产生空白grow(false)Split与普通表格列一样会自动调整空白以保证各列之间有合理的比例分隔。如果你不希望某个列占据多余空白可以对其使用grow(false)。下面的示例让头像图片紧贴姓名列use Filament\Support\Enums\FontWeight; use Filament\Tables\Columns\ImageColumn; use Filament\Tables\Columns\Layout\Split; use Filament\Tables\Columns\TextColumn; Split::make([ ImageColumn::make(avatar) -circular() -grow(false), TextColumn::make(name) -weight(FontWeight::Bold) -searchable() -sortable(), TextColumn::make(email), ])其余允许grow()的列会自动扩展以消化新释放出来的空间。从源码看grow(false)的能力来自CanGrowtrait被布局基类 Component.php 引入渲染时对应容器会带上fi-growable类。在 Split 内堆叠Stack在Split内部你可以用Stack把多列垂直堆叠起来从而在桌面上用更少的列展示更多数据use Filament\Support\Enums\FontWeight; use Filament\Tables\Columns\ImageColumn; use Filament\Tables\Columns\Layout\Split; use Filament\Tables\Columns\Layout\Stack; use Filament\Tables\Columns\TextColumn; Split::make([ ImageColumn::make(avatar) -circular(), TextColumn::make(name) -weight(FontWeight::Bold) -searchable() -sortable(), Stack::make([ TextColumn::make(phone) -icon(heroicon-m-phone), TextColumn::make(email) -icon(heroicon-m-envelope), ]), ])在移动端隐藏 Stack与单个列类似你可以基于浏览器的响应式断点隐藏整个Stack使用visibleFrom()方法use Filament\Support\Enums\FontWeight; use Filament\Tables\Columns\ImageColumn; use Filament\Tables\Columns\Layout\Split; use Filament\Tables\Columns\Layout\Stack; use Filament\Tables\Columns\TextColumn; Split::make([ ImageColumn::make(avatar) -circular(), TextColumn::make(name) -weight(FontWeight::Bold) -searchable() -sortable(), Stack::make([ TextColumn::make(phone) -icon(heroicon-m-phone), TextColumn::make(email) -icon(heroicon-m-envelope), ])-visibleFrom(md), ])对齐堆叠内容默认情况下Stack内的列按起始位置start对齐。你也可以把列对齐到Alignment::Center或Alignment::Enduse Filament\Support\Enums\Alignment; use Filament\Support\Enums\FontWeight; use Filament\Tables\Columns\ImageColumn; use Filament\Tables\Columns\Layout\Split; use Filament\Tables\Columns\Layout\Stack; use Filament\Tables\Columns\TextColumn; Split::make([ ImageColumn::make(avatar) -circular(), TextColumn::make(name) -weight(FontWeight::Bold) -searchable() -sortable(), Stack::make([ TextColumn::make(phone) -icon(heroicon-m-phone) -grow(false), TextColumn::make(email) -icon(heroicon-m-envelope) -grow(false), ]) -alignment(Alignment::End) -visibleFrom(md), ])注意必须确保 Stack 内的列设置了grow(false)否则它们会拉伸填满 Stack 的整个宽度并遵循各自的对齐配置而不是 Stack 的。该能力来自HasAlignmenttrait渲染时会在容器上追加fi-align-{alignment}类见 Stack.php。堆叠内容的间距默认情况下堆叠内容之间没有垂直内边距。要增加间距可使用space()方法它接受1、2或3分别对应 Tailwind 的间距刻度use Filament\Tables\Columns\Layout\Stack; use Filament\Tables\Columns\TextColumn; Stack::make([ TextColumn::make(phone) -icon(heroicon-m-phone), TextColumn::make(email) -icon(heroicon-m-envelope), ])-space(1)从 Stack.php 的源码可以看到1/2/3分别映射为fi-gap-sm、fi-gap-md、fi-gap-lg三个间距类。用 Grid 控制列宽某些情况下当列包含大量内容时Split会产生不一致的宽度。这是因为Split内部基于 Flexbox 实现每一行独立决定如何分配空间。此时可以改用Grid布局它基于 CSS Grid Layout让你可以精确控制列宽use Filament\Tables\Columns\Layout\Grid; use Filament\Tables\Columns\TextColumn; Grid::make([ lg 2, ]) -schema([ TextColumn::make(phone) -icon(heroicon-m-phone), TextColumn::make(email) -icon(heroicon-m-envelope), ])从lg断点开始这些列在网格内始终平分宽度。你还可以自定义其他断点下的网格列数use Filament\Tables\Columns\Layout\Grid; use Filament\Tables\Columns\Layout\Stack; use Filament\Tables\Columns\TextColumn; Grid::make([ lg 2, 2xl 4, ]) -schema([ Stack::make([ TextColumn::make(name), TextColumn::make(job), ]), TextColumn::make(phone) -icon(heroicon-m-phone), TextColumn::make(email) -icon(heroicon-m-envelope), ])甚至可以控制每个组件在各个断点下占据多少网格列columnSpanuse Filament\Tables\Columns\Layout\Grid; use Filament\Tables\Columns\Layout\Stack; use Filament\Tables\Columns\TextColumn; Grid::make([ lg 2, 2xl 5, ]) -schema([ Stack::make([ TextColumn::make(name), TextColumn::make(job), ])-columnSpan([ lg full, 2xl 2, ]), TextColumn::make(phone) -icon(heroicon-m-phone) -columnSpan([ 2xl 2, ]), TextColumn::make(email) -icon(heroicon-m-envelope), ])从 Grid.php 的源码看Grid::make()的默认列数为2并且当你传入纯整数时如Grid::make(2)内部会自动转换为[lg 2]渲染时容器会带上fi-ta-grid类并根据每个断点的列数决定使用小间距fi-gap-sm单列时还是大间距fi-gap-lg多列时。可折叠内容当你使用Split或Stack这类列布局时还可以添加可折叠内容。这在不想一次性展示全部数据但又希望用户无需离开页面即可按需查看时非常有用。Split与Stack组件本身都可以设置collapsible()此外还有一个专门的Panel组件它提供了预置的背景色与圆角用来把可折叠内容与其余部分区分开use Filament\Support\Enums\FontWeight; use Filament\Tables\Columns\ImageColumn; use Filament\Tables\Columns\Layout\Panel; use Filament\Tables\Columns\Layout\Split; use Filament\Tables\Columns\Layout\Stack; use Filament\Tables\Columns\TextColumn; [ Split::make([ ImageColumn::make(avatar) -circular(), TextColumn::make(name) -weight(FontWeight::Bold) -searchable() -sortable(), ]), Panel::make([ Stack::make([ TextColumn::make(phone) -icon(heroicon-m-phone), TextColumn::make(email) -icon(heroicon-m-envelope), ]), ])-collapsible(), ]Panel组件在渲染时会给容器加上fi-ta-panel类见 Panel.php这就是预置背景与圆角样式的来源。默认情况下可折叠内容处于折叠状态你也可以通过collapsed(false)让面板默认展开use Filament\Tables\Columns\Layout\Panel; use Filament\Tables\Columns\Layout\Split; use Filament\Tables\Columns\TextColumn; Panel::make([ Split::make([ TextColumn::make(phone) -icon(heroicon-m-phone), TextColumn::make(email) -icon(heroicon-m-envelope), ])-from(md), ])-collapsed(false)从布局基类 Component.php 的源码可以看到collapsible()设置isCollapsible标志collapsed()会同时调用collapsible()并把折叠状态写入isCollapsed属性支持闭包求值。将记录排列为网格contentGrid()如果你的数据更适合以网格而非列表的形式展示Filament 同样支持。只需使用$table-contentGrid()方法use Filament\Tables\Columns\Layout\Stack; use Filament\Tables\Table; public function table(Table $table): Table { return $table -columns([ Stack::make([ // Columns ]), ]) -contentGrid([ md 2, xl 3, ]); }在这个示例中记录将按网格展示移动端仅 1 列从md断点起2 列从xl断点起3 列。这些配置完全可自定义sm到2xl之间的任何断点都可以设置1到12列。该方法定义于 HasContent.php该 trait 同时提供了content()自定义整行内容视图与contentFooter()内容底部视图方法。自定义 HTMLView 组件你可以使用View组件向表格行中添加自定义 HTML它同样支持collapsible()use Filament\Support\Enums\FontWeight; use Filament\Tables\Columns\ImageColumn; use Filament\Tables\Columns\Layout\Split; use Filament\Tables\Columns\Layout\View; use Filament\Tables\Columns\TextColumn; [ Split::make([ ImageColumn::make(avatar) -circular(), TextColumn::make(name) -weight(FontWeight::Bold) -searchable() -sortable(), ]), View::make(users.table.collapsible-row-content) -collapsible(), ]然后创建/resources/views/users/table/collapsible-row-content.blade.php文件并写入 HTML通过$getRecord()访问表格记录p classpx-4 py-3 bg-gray-100 rounded-lg span classfont-medium Email address: /span span {{ $getRecord()-email }} /span /p嵌入其他组件你还可以通过components()方法向View组件传入列或其他布局组件use Filament\Support\Enums\FontWeight; use Filament\Tables\Columns\ImageColumn; use Filament\Tables\Columns\Layout\Split; use Filament\Tables\Columns\Layout\View; use Filament\Tables\Columns\TextColumn; [ Split::make([ ImageColumn::make(avatar) -circular(), TextColumn::make(name) -weight(FontWeight::Bold) -searchable() -sortable(), ]), View::make(users.table.collapsible-row-content) -components([ TextColumn::make(email) -icon(heroicon-m-envelope), ]) -collapsible(), ]随后在 Blade 文件中渲染这些组件div classpx-4 py-3 bg-gray-100 rounded-lg foreach ($getComponents() as $layoutComponent) {{ $layoutComponent -record($getRecord()) -recordKey($getRecordKey()) -rowLoop($getRowLoop()) -renderInLayout() }} endforeach /div这里调用的renderInLayout()正是布局组件渲染的核心入口——它在布局基类 Component.php 中实现如果组件被隐藏则返回null否则根据columnSpan/columnStart、grow、hiddenFrom/visibleFrom组装出带网格列与响应式类的容器属性再渲染组件自身的 HTML。布局组件的底层骨架所有布局组件Split、Stack、Grid、Panel、View都继承自Filament\Tables\Columns\Layout\Component见 Component.php它聚合了以下能力schema()/components()接收列或子布局组件的数组也支持闭包惰性求值getComponents()会自动为每个子组件设置所属布局使其能通过getTable()访问到宿主表格getColumns()递归收集布局树中的所有Column这保证了排序、搜索、隐藏等功能对布局内的列依然生效collapsible()/collapsed()/isCollapsed()可折叠能力折叠状态支持闭包动态求值renderInLayout()按columnSpan、grow、hiddenFrom/visibleFrom等配置输出带响应式类的包裹容器通过CanGrow、CanSpanColumns、CanBeHidden、HasRecord、HasRowLoopObject、HasExtraAttributes等 trait 获得与普通列一致的横向能力。布局选择建议想要快速响应式直接用$table-stackedOnMobile()一行代码即可需要突出头像、姓名等主信息次要信息分组收纳SplitStack组合配合from()、visibleFrom()、alignment()、space()精细调节列内容多、宽度不一致改用GridcolumnSpan用 CSS Grid 保证列宽一致性次要数据默认隐藏、按需展开使用Panel::make(...)-collapsible()或Split/Stack的collapsible()数据本身适合卡片网格contentGrid()配合Stack布局可替代传统列表需要完全自由的 HTMLView组件 Blade 模板必要时用components()嵌入标准列组件。布局组件在tables包中的实现均位于 packages/tables/src/Columns/Layout 目录相关表格级能力stackedOnMobile、contentGrid分别见 CanBeStackedOnMobile.php 与 HasContent.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),仅供参考
返回列表