Filament Tabs 布局组件完全指南:表单与 InfoList 中的选项卡分区、徽标与状态持久化

发布时间:2026/9/11 20:33:01
Filament Tabs 布局组件完全指南:表单与 InfoList 中的选项卡分区、徽标与状态持久化
Filament Tabs 布局组件完全指南表单与 InfoList 中的选项卡分区、徽标与状态持久化【免费下载链接】filamentA powerful open-source UI framework for Laravel • Build and ship apps admin panels fast with Livewire项目地址: https://gitcode.com/GitHub_Trending/fi/filamentTabs选项卡是 Filament Schema 体系中最常用的布局组件之一用于将冗长的表单或 InfoList 拆分为多个互不干扰的分区从而显著降低单屏信息密度。本指南以 packages/schemas/docs/04-tabs.md 为核心结合 Tabs 组件源码 与 测试用例 展开讲解你将掌握 Tabs 的声明方式、默认激活项、图标与徽标、按需加载defer、网格布局、垂直模式以及两种会话状态持久化方案可直接复用于表单Forms与信息列表Infolists等任意 Schema 场景。一、快速上手声明一组选项卡当 Schema 内容较长、字段较多时可以用Tabs组件把组件分组到多个选项卡中同一时间只展示一组内容use Filament\Schemas\Components\Tabs; use Filament\Schemas\Components\Tabs\Tab; Tabs::make(Tabs) -tabs([ Tab::make(Tab 1) -schema([ // 组件列表... ]), Tab::make(Tab 2) -schema([ // 组件列表... ]), Tab::make(Tab 3) -schema([ // 组件列表... ]), ])从源码角度看Tabs::make()返回的是 Tabs.php 中通过容器解析构建的组件实例而tabs()方法本质上是把传入的Tab数组直接注册为子组件$this-components($tabs)见 Tabs.php#L98-L103。因此Tab与普通 Schema 组件遵循完全相同的生命周期、渲染与状态绑定规则。几点实现细节可从源码确认Tabs组件默认在setUp()中根据标签自动生成一个 key格式为slug(标签)::tabs见 Tabs.php#L82-L92无需手动指定每个Tab也会自动获得slug(标签)::tab形式的 key见 Tab.php#L60-L65渲染时仅会渲染当前激活选项卡的内容面板其他选项卡的 DOM 在首次进入前不会输出这为下文介绍的内容延迟加载奠定了基础。二、设置默认激活选项卡默认情况下第一个选项卡处于打开状态。可以通过activeTab()修改默认激活的选项卡use Filament\Schemas\Components\Tabs; use Filament\Schemas\Components\Tabs\Tab; Tabs::make(Tabs) -tabs([ Tab::make(Tab 1) -schema([ // ... ]), Tab::make(Tab 2) -schema([ // ... ]), Tab::make(Tab 3) -schema([ // ... ]), ]) -activeTab(2)源码中activeTab属性默认值为1Tabs.php#L45getActiveTab()在未使用 URL 持久化时返回evaluate($this-activeTab)Tabs.php#L145-L160。测试用例 TabsTest.php#L65-L73 验证了默认值为 1、设置后变为 3 的行为。activeTab()同样支持传入闭包进行动态计算闭包中可以注入 Schema 组件相关的实用工具如当前 Livewire 组件、状态路径等。三、为选项卡添加图标选项卡可以配置图标使用icon()方法即可use Filament\Schemas\Components\Tabs; use Filament\Schemas\Components\Tabs\Tab; use Filament\Support\Icons\Heroicon; Tabs::make(Tabs) -tabs([ Tab::make(Notifications) -icon(Heroicon::Bell) -schema([ // ... ]), // ... ])图标参数除了Filament\Support\Icons\Heroicon枚举仓库中定义于 packages/support/src/Icons/Heroicon.php也支持传入字符串形式的图标名称如heroicon-o-bell闭包同样可用。关于图标体系与自定义图标的完整说明可参考 图标样式文档。从渲染源码看图标会被放置在标签文本之前IconPosition::Before生成逻辑位于 Tabs.php#L436-L446。测试 TabTest.php#L223-L262 验证了字符串、BackedEnum、闭包三种传值方式均可用且默认无图标时返回null。设置图标位置默认图标位于标签文本左侧可通过iconPosition()把图标放到文本之后use Filament\Schemas\Components\Tabs; use Filament\Schemas\Components\Tabs\Tab; use Filament\Support\Enums\IconPosition; use Filament\Support\Icons\Heroicon; Tabs::make(Tabs) -tabs([ Tab::make(Notifications) -icon(Heroicon::Bell) -iconPosition(IconPosition::After) -schema([ // ... ]), // ... ])IconPosition枚举定义于Filament\Support\Enums\IconPosition取值为Before默认与After。渲染时组件会根据该位置决定图标输出在标签span的前面还是后面Tabs.php#L436-L446。四、为选项卡设置徽标Badge徽标用于在选项卡上显示数字或短文本例如未读消息数use Filament\Schemas\Components\Tabs; use Filament\Schemas\Components\Tabs\Tab; Tabs::make(Tabs) -tabs([ Tab::make(Notifications) -badge(5) -schema([ // ... ]), // ... ])徽标颜色可通过badgeColor()指定支持danger、info、success、warning、gray、primary等 Filament 内置颜色也支持自定义颜色use Filament\Schemas\Components\Tabs; use Filament\Schemas\Components\Tabs\Tab; Tabs::make(Tabs) -tabs([ Tab::make(Notifications) -badge(5) -badgeColor(info) -schema([ // ... ]), // ... ])从源码看Tab复用了一整套徽标能力HasBadge、HasBadgeTooltip、HasIcon、HasIconPosition见 Tab.php#L23-L29因此除了badge()与badgeColor()你还可以使用badgeIcon()/badgeIconPosition()为徽标添加图标并控制位置Tab.php#L107-L133badgeTooltip()为徽标提供悬停提示文本badge()与badgeColor()均支持闭包动态计算测试 TabTest.php#L78-L138 对字符串、数字、闭包以及清除传null行为均有覆盖。关于颜色的可选值与自定义方式可参考 颜色样式文档。延迟加载徽标deferBadge()如果徽标背后是昂贵的查询例如未读通知计数初始页面加载可能变慢。此时可以用deferBadge()让徽标值在页面渲染完成后异步加载use Filament\Schemas\Components\Tabs; use Filament\Schemas\Components\Tabs\Tab; Tabs::make(Tabs) -key(notifications-tabs) -tabs([ Tab::make(Notifications) -badge(static fn (): int Notification::query()-where(unread, true)-count()) -deferBadge() -schema([ // ... ]), // ... ])使用deferBadge()时有两条硬性约束原文档以警告框形式强调务必遵守badge()必须返回闭包。如果直接写badge(Notification::query()-count())查询会在组件构建时立即执行延迟加载便失去了意义Tabs组件必须设置key()。延迟徽标需要向服务端发起异步请求没有 key 时服务端无法定位到正确的组件。底层实现中deferBadge()将isBadgeDeferred置为trueTab.php#L135-L145。渲染时Tabs::toEmbeddedHtml()会先调用hasDeferredBadges()检测是否存在延迟徽标Tabs.php#L947-L960若有则注入一段 Alpine.js 数据对象通过$wire.callSchemaComponentMethod(..., getDeferredTabBadges)发起异步请求Tabs.php#L336-L356服务端由标有#[ExposedLivewireMethod]与#[Renderless]的getDeferredTabBadges()方法计算所有延迟徽标并返回Tabs.php#L898-L945。在徽标加载期间选项卡上会显示一个小型加载指示器loading indicator数据返回后被真实徽标值替换。测试 TabsTest.php#L52-L63 通过callSchemaComponentMethod直接调用了getDeferredTabBadges验证返回的徽标集合只包含被延迟的选项卡示例中返回1 [badge 42]未延迟的0不出现。五、延迟加载选项卡内容如果某个选项卡的内容本身渲染开销很大可以给它传入一个独立的Schema对象并调用deferLoading()。激活选项卡的内容会在进入视口viewport时加载未激活选项卡的内容则要等到被选中后才加载use Filament\Forms\Components\TextInput; use Filament\Schemas\Components\Tabs; use Filament\Schemas\Components\Tabs\Tab; use Filament\Schemas\Schema; Tabs::make(Settings) -key(settingsTabs) -tabs([ Tab::make(Profile) -key(profileTab) -schema( Schema::make() -components([ TextInput::make(name), ]) -deferLoading(), ), Tab::make(Notifications) -key(notificationsTab) -schema( Schema::make() -components([ // ... ]) -deferLoading(), ), ])每个延迟加载的 Schema 必须拥有唯一 key。上述示例中Tab上的key()会被其子 Schema 继承而Tabs组件上的key()则用于把不同选项卡的 Schema 命名空间隔离避免相互冲突。更完整的原理说明见 Schema 总览文档 中Deferring the loading of a child schema一节延迟的 Schema 初始渲染为一个加载指示器指示器进入视口后才会在新的请求中渲染该 Schema如果延迟 Schema 在加载前存在校验错误它会自动加载以展示错误信息处于隐藏容器如折叠的 Section 或未激活的 Tab内的延迟 Schema 不会加载直到其父级被展开并进入视口Schema 一旦加载完成会在 Livewire 组件的整个生命周期内保持加载状态不会重复请求。六、在选项卡内使用网格列布局与 Section、Fieldset 等其他布局组件一样Tab也支持columns()方法来自定义选项卡内部内容的网格布局use Filament\Schemas\Components\Tabs; use Filament\Schemas\Components\Tabs\Tab; Tabs::make(Tabs) -tabs([ Tab::make(Tab 1) -schema([ // ... ]) -columns(3), // ... ])columns()的取值方式与全局网格系统完全一致整数如columns(2)表示在lg断点及以上使用 2 列更小的设备上为 1 列数组如columns([md 2, xl 4])可针对不同断点指定不同列数也可用default键指定小屏默认列数。从源码看Tab::getAllColumns()在自身未显式设置列数时会向上继承父容器的列配置Tab.php#L71-L78即选项卡默认遵循外层 Schema 的网格。完整网格系统说明见 布局文档。七、禁用可横向滚动的选项卡默认情况下选项卡以水平方式渲染当选项卡数量超出可用宽度时会横向滚动。可以使用scrollable(false)关闭滚动use Filament\Schemas\Components\Tabs; Tabs::make(Tabs) -tabs([ // ... ]) -scrollable(false)关闭滚动后组件会自动检测可用宽度如果所有选项卡无法完整放下会出现一个下拉按钮超出宽度的选项卡会被自动收进下拉菜单中渲染实现见 Tabs.php#L456-L619其中filamentDropdown负责下拉交互。源码层面isScrollable属性默认值为trueTabs.php#L61scrollable()支持传入闭包动态控制测试见 TabsTest.php#L117-L128 与 TabsTest.php#L156-L161。在非滚动模式下导航栏会绑定withinDropdownMounted相关逻辑以决定哪些选项卡内联展示、哪些归入下拉列表Tabs.php#L278-L302。八、使用垂直选项卡默认的选项卡是水平排列的通过vertical()可以改为垂直布局选项卡列表在左、内容在右use Filament\Schemas\Components\Tabs; use Filament\Schemas\Components\Tabs\Tab; Tabs::make(Tabs) -tabs([ Tab::make(Tab 1) -schema([ // ... ]), Tab::make(Tab 2) -schema([ // ... ]), Tab::make(Tab 3) -schema([ // ... ]), ]) -vertical()vertical()也接受布尔值参数便于结合功能开关动态控制支持闭包use Filament\Schemas\Components\Tabs; Tabs::make(Tabs) -tabs([ // ... ]) -vertical(FeatureFlag::active())源码中isVertical属性默认falseTabs.php#L63isVertical()在渲染时会向最外层容器与导航栏添加fi-verticalCSS 类Tabs.php#L311-L326由样式层完成垂直布局切换。九、移除默认的样式容器默认情况下选项卡与内容会被包裹在一个卡片样式的容器中。如果希望移除这个样式容器例如嵌入到其他自定义布局中使用contained(false)use Filament\Schemas\Components\Tabs; use Filament\Schemas\Components\Tabs\Tab; Tabs::make(Tabs) -tabs([ Tab::make(Tab 1) -schema([ // ... ]), Tab::make(Tab 2) -schema([ // ... ]), Tab::make(Tab 3) -schema([ // ... ]), ]) -contained(false)isContained默认值为true测试见 TabsTest.php#L323-L342contained()同样支持闭包。容器与导航栏上的fi-contained类会随该值同步出现或移除Tabs.php#L311-L326。十、在会话中持久化当前选项卡localStorage默认情况下当前选中的选项卡不会保存在浏览器本地存储中。使用persistTab()可以开启持久化但必须同时为 Tabs 组件设置唯一的id()以区分应用中的其他选项卡组——这个 id 会作为 localStorage 的 keyuse Filament\Schemas\Components\Tabs; Tabs::make(Tabs) -tabs([ // ... ]) -persistTab() -id(order-tabs)persistTab()也接受布尔值参数支持闭包用于条件开启use Filament\Schemas\Components\Tabs; Tabs::make(Tabs) -tabs([ // ... ]) -persistTab(FeatureFlag::active()) -id(order-tabs)persistTab()由独立的 CanPersistTab trait 提供其isTabPersisted属性默认false。渲染时前端 Alpine 组件会收到isTabPersisted与tab基于 id 的持久化读取表达式两个参数Tabs.php#L368-L383由tabsSchemaComponent前端模块完成 localStorage 的读写。测试 TabsTest.php#L229-L254 覆盖了默认值、开关与闭包三种情况。十一、在 URL 查询字符串中持久化当前选项卡除了 localStorage还可以把当前选项卡同步到 URL 的查询字符串中方便分享链接时保留上下文。使用persistTabInQueryString()use Filament\Schemas\Components\Tabs; use Filament\Schemas\Components\Tabs\Tab; Tabs::make(Tabs) -tabs([ Tab::make(Tab 1) -schema([ // ... ]), Tab::make(Tab 2) -schema([ // ... ]), Tab::make(Tab 3) -schema([ // ... ]), ]) -persistTabInQueryString()开启后当前选项卡会以tab作为查询字符串参数名写入 URL。也可以传入自定义参数名use Filament\Schemas\Components\Tabs; use Filament\Schemas\Components\Tabs\Tab; Tabs::make(Tabs) -tabs([ Tab::make(Tab 1) -schema([ // ... ]), Tab::make(Tab 2) -schema([ // ... ]), Tab::make(Tab 3) -schema([ // ... ]), ]) -persistTabInQueryString(settings-tab)persistTabInQueryString()同样支持闭包。其底层行为可以从源码确认persistTabInQueryString()默认参数为tab存入tabQueryStringKey属性Tabs.php#L138-L143getActiveTab()在 URL 持久化开启时会优先解析查询字符串遍历子选项卡按 id 匹配查询参数值并返回对应的序号Tabs.php#L147-L157找不到匹配项时回退到activeTab()配置的值传null可以清除该配置恢复默认行为测试见 TabsTest.php#L147-L154。两种持久化方式的对比方式方法存储位置附加要求适用场景会话持久化persistTab()浏览器 localStorage必须设置唯一id()记住单个用户的浏览位置URL 持久化persistTabInQueryString()URL 查询字符串无参数名默认tab可自定义分享链接、服务端可读取当前选项卡十二、进阶与 Livewire 属性绑定的选项卡除文档主流程外源码中还存在一种高级用法通过livewireProperty()把选项卡直接绑定到 Livewire 组件的某个属性上。此时点击选项卡会生成wire:click$set(属性名, tabKey)激活状态完全由该属性驱动Tabs.php#L642-L781。测试 TabsTest.php#L177-L198 验证了渲染出的$set(...)指令且选项卡内的嵌套 Action 也能正常工作TabsTest.php#L200-L204。此外Tab还提供了两个面向数据查询的扩展点query()/modifyQueryUsing()在解析选项卡关联记录时修改底层 Eloquent 查询Tab.php#L80-L105excludeQueryWhenResolvingRecord()跳过查询直接解析记录源码注释明确警告——不要用于强制授权范围的选项卡如按租户或用户归属限制记录否则会允许通过直接 URL 访问该选项卡作用域之外的记录Tab.php#L200-L215。十三、完整参考Tabs 方法速查表方法作用默认值是否支持闭包tabs([...])注册选项卡列表—是activeTab(int)设置默认激活的选项卡从 1 开始1是icon()/iconPosition()设置选项卡图标及位置无图标位置Before是badge()/badgeColor()/badgeIcon()/badgeTooltip()设置徽标内容、颜色、图标与提示无徽标是deferBadge()异步加载徽标需闭包 badge 组件key()false是Schema::make()-deferLoading()延迟加载选项卡内容每个延迟 Schema 需唯一 key—是columns()设置选项卡内部网格列数继承父级是scrollable(bool)是否允许横向滚动关闭后超出部分进入下拉true是vertical(bool)垂直选项卡布局false是contained(bool)是否保留卡片样式容器true是persistTab()localStorage 持久化当前选项卡需id()false是persistTabInQueryString(key)URL 查询字符串持久化当前选项卡关闭参数名tab是以上所有 API 均有对应测试覆盖可进一步参阅 TabsTest.php 与 TabTest.php源码实现见 Tabs.php 与 Tab.php。结合 布局文档 中的网格系统与 Schema 总览文档 中的延迟加载机制即可在 Filament 表单与 InfoList 中构建出结构清晰、性能可控的多分区界面。【免费下载链接】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),仅供参考