尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Filament Loading Indicator 组件完全指南:内置用法与自定义实现

Filament Loading Indicator 组件完全指南:内置用法与自定义实现 Filament Loading Indicator 组件完全指南内置用法与自定义实现【免费下载链接】filamentA powerful open-source UI framework for Laravel • Build and ship apps admin panels fast with Livewire项目地址: https://gitcode.com/GitHub_Trending/fi/filamentFilament 的 Loading Indicator加载指示器是一个基于 SVG 的轻量级动画组件用于在页面、表单、按钮或表格等待异步操作完成时给出视觉反馈。本文将以 Loading Indicator 官方文档 为核心结合仓库源码support 包与测试用例完整讲解该组件的标准用法、样式规则、无障碍处理以及如何通过服务容器替换为自定义加载动画的实现方案。读完本文你将能够在 Filament 应用中直接使用x-filament::loading-indicator组件理解其底层渲染链路Blade 组件 →generate_loading_indicator_html()→ 契约绑定并掌握在服务提供者中绑定自定义LoadingIndicator实现以全局替换默认 spinner 的完整步骤。组件简介与基本用法Loading Indicator 是一个动画 SVG用于向用户提示某操作正在进行中。它不依赖任何 JavaScript 初始化渲染后即具备旋转动画可以直接嵌入到任意 Blade 视图中x-filament::loading-indicator classh-5 w-5 /该组件会输出一个双圆环风格的旋转 SVG外层为opacity0.2的完整圆环内层为填充色弧段通过 CSS 旋转动画呈现转圈效果。class属性用于控制尺寸——在上述示例中h-5 w-5将其限制为 20×20 像素。默认动画定义在 loading-indicator.css.fi-loading-indicator { apply motion-safe:animate-spin; }注意motion-safe:前缀动画仅在系统未开启减少动态效果prefers-reduced-motion时生效这符合可访问性最佳实践。组件内部的实现方式x-filament::loading-indicator的 Blade 视图本身只有一行核心逻辑委托给 support 包的全局函数{{ \Filament\Support\generate_loading_indicator_html($attributes) }}对应源码见 loading-indicator.blade.php。而 helpers.php 中的generate_loading_indicator_html()函数负责默认使用IconSize::Medium尺寸若未显式指定将传入属性合并进fi-icon fi-loading-indicator及fi-size-*样式类解析并缓存LoadingIndicator契约实例调用实例的toHtml()方法生成 HTML。if (! function_exists(Filament\Support\generate_loading_indicator_html)) { function generate_loading_indicator_html(?ComponentAttributeBag $attributes null, ?IconSize $size null): Htmlable { $size ?? IconSize::Medium; $attributes ($attributes ?? new FilamentComponentAttributeBag)-class([ fi-icon fi-loading-indicator, fi-size-{$size-value}, ]); static $loadingIndicator null; $loadingIndicator ?? app(LoadingIndicator::class); return new HtmlString($loadingIndicator-toHtml($attributes)); } }从源码结构可以看出加载指示器在整个 Filament 生态中是统一复用的按钮、链接、徽章、下拉菜单项、输入框、文件上传等组件在进入加载状态时都会通过同一套机制渲染同一个 spinner例如 icon-button.blade.php 会在wire:loading状态下调用该函数。因此替换加载指示器实现即可一次性影响所有组件。替换默认的加载指示器Filament 通过 Laravel 的服务容器解耦了加载指示器的渲染逻辑。默认情况下Filament\Support\Contracts\LoadingIndicator契约绑定到Filament\Support\View\DefaultLoadingIndicator实现绑定声明位于 SupportServiceProvider.php$this-app-bind(LoadingIndicator::class, DefaultLoadingIndicator::class);要换成你自己的实现只需在某个服务提供者中重新绑定该契约use App\Support\CustomLoadingIndicator; use Filament\Support\Contracts\LoadingIndicator; public function register(): void { $this-app-bind(LoadingIndicator::class, CustomLoadingIndicator::class); }仓库测试 LoadingIndicatorTest.php 精确验证了这条替换链路it(allows swapping the loading indicator implementation via the container, function (): void { app()-bind(LoadingIndicator::class, CustomLoadingIndicator::class); expect(app(LoadingIndicator::class)) -toBeInstanceOf(CustomLoadingIndicator::class); expect(app(LoadingIndicator::class)-toHtml(new ComponentAttributeBag)) -toBe(divCustom/div); });测试还确认了两个默认行为LoadingIndicator契约默认解析为DefaultLoadingIndicator实例DefaultLoadingIndicator::toHtml()输出svg并原样透传传入的属性测试断言fi-custom出现在输出中。契约与实现的要求你的自定义类必须实现LoadingIndicator契约。该契约定义在 Contracts/LoadingIndicator.php只有一个方法interface LoadingIndicator { public function toHtml(ComponentAttributeBag $attributes): string; }toHtml()接收一个Illuminate\View\ComponentAttributeBag已包含类名、尺寸、wire:target、wire:loading等运行时属性并返回加载指示器的 HTML 字符串namespace App\Support; use Filament\Support\Contracts\LoadingIndicator; use Illuminate\View\ComponentAttributeBag; class CustomLoadingIndicator implements LoadingIndicator { public function toHtml(ComponentAttributeBag $attributes): string { return HTML svg {$attributes-toHtml()} !-- ... -- /svg HTML; } }传入的$attributes中已经包含fi-icon fi-loading-indicator以及尺寸相关的 hook 类如fi-size-md因此请将它们直接转发到你的根元素上以保证样式系统、动画钩子与组件缓存机制正常工作。参考默认实现的细节了解默认实现 DefaultLoadingIndicator.php 有助于你写出等价的替换实现。它做了两件事合并无障碍属性默认将aria-hiddentrue合并进属性并标记escape: false即不转义该值避免屏幕阅读器重复播报加载中。注释说明spinner 是装饰性元素加载状态本身由外层控件的aria-label或rolestatus传达调用方仍可通过显式传入自己的aria-hidden覆盖此默认值。输出标准双圆环 SVG外层圆环opacity0.2、内层实心弧段均使用currentColor填充因此颜色自动跟随父元素的文本颜色。public function toHtml(ComponentAttributeBag $attributes): string { $attributes $attributes-merge([aria-hidden true], escape: false); return HTML svg fillnone viewBox0 0 24 24 xmlnshttp://www.w3.org/2000/svg {$attributes-toHtml()} path clip-ruleevenodd d... fill-ruleevenodd fillcurrentColor opacity0.2/path path d... fillcurrentColor/path /svg HTML; }自定义实现时建议保留aria-hiddentrue的默认合并逻辑或按你的场景自行决定并注意toHtml()返回的是字符串而非视图若想在返回内容中包含 Blade 渲染结果请先自行编译成字符串。性能与缓存注意事项重要仓库源码明确展示了实例的缓存策略generate_loading_indicator_html()内部使用static $loadingIndicator静态变量首次解析后便在整个 PHP 进程生命周期内缓存LoadingIndicator实例static $loadingIndicator null; $loadingIndicator ?? app(LoadingIndicator::class);这意味着在普通 FPM 环境下每个请求进程各自缓存绑定在register()中声明即可在Laravel Octane等常驻内存环境下该实例在 worker 启动时只解析一次不会在请求之间重新解析。因此你的绑定必须在服务提供者中完成切勿在运行时如中间件、控制器、Blade 视图中动态重新绑定否则不会生效。这一点在原文档中亦有明确警告绑定请始终放在服务提供者的register()方法里保持绑定时机在进程启动阶段。实际使用场景与 Livewire 加载状态配合虽然本组件可独立使用但更常见的场景是结合 Livewire 的wire:loading指令实现异步请求期间显示 spinnerbutton wire:clicksave span wire:loading.remove wire:targetsave保存/span x-filament::loading-indicator wire:loading.delay.default wire:targetsave classh-4 w-4 / /buttonFilament 内部组件也是同样的模式。以 icon-button.blade.php 为例当存在wire:click/wire:target目标或表单提交时组件会判断hasLoadingIndicator然后通过wire:loading.attr禁用按钮并用wire:loading.delay.delay控制 spinner 的显示时机wire:loading.remove.delay. . $loadingDelay $hasLoadingIndicator, wire:target $hasLoadingIndicator ? $loadingIndicatorTarget : false,其中$loadingDelay读取自配置文件filament.php的livewire_loading_delay项默认default即 Livewire 标准的 200ms 延迟。该配置定义在 packages/support/config/filament.php并支持两种特殊取值none指示器立即显示适合高延迟网络环境default应用 Livewire 的 200ms 标准延迟。这一延迟机制避免了对极短请求的闪烁体验是 Filament 全站加载反馈的一致基础。进阶表单字段内的加载指示器在表单系统中加载指示器还承担字段联动请求的反馈职责。以 FileUpload.php 为例文件上传字段支持通过loadingIndicatorPosition()配置 spinner 出现的位置默认right也可设为left等protected string | Closure $loadingIndicatorPosition right; public function loadingIndicatorPosition(string | Closure | null $position): static { $this-loadingIndicatorPosition $position; return $this; } public function getLoadingIndicatorPosition(): string { return $this-evaluate($this-loadingIndicatorPosition); }对应的测试见 FileUploadTest.php它验证了位置取值right与left的读写行为。同理Field.php 中字段输入框也会在存在wire:target目标时渲染加载指示器。这说明 Loading Indicator 组件贯穿 Filament 的按钮、链接、表单字段、表格头部等全部交互点是统一的进程反馈基建。小结使用x-filament::loading-indicator classh-5 w-5 /即可渲染一个随系统减少动态效果偏好而启停的旋转 SVG样式尺寸通过class控制颜色跟随currentColor默认带motion-safe:animate-spin动画替换在服务提供者register()中bind(LoadingIndicator::class, YourImplementation::class)实现toHtml(ComponentAttributeBag): string并将传入属性转发给根元素契约与缓存契约只含一个toHtml()方法实例在进程生命周期内被静态缓存Octane 下务必在启动阶段绑定无障碍默认实现合并aria-hiddentrue加载状态语义由外层控件承担验证依据默认绑定、SVG 透传、容器替换三条行为均有 LoadingIndicatorTest.php 测试覆盖。无论是直接使用默认 spinner还是通过容器注入自定义品牌加载动画Filament 的 Loading Indicator 组件都提供了足够简单且可扩展的接入方式。【免费下载链接】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),仅供参考
返回列表