本文将介绍如何使用 Filament 插件(Widget)创建统计卡片,用来展示用户统计信息。我们将展示如何使用 Livewire 生命周期 hook 和事件,在用户表修改时刷新插件。
首先,安装一个名为 filament-widget-examples 的 Laravel 应用:
laravel new filament-widget-examples
然后使用命令安装 Filament:
cd filament-widget-examplescomposer require filament/filament
Filament 推荐添加以下内容到 composer.json
的 post-update-cmd
:
"post-update-cmd": [ // ... "@php artisan filament:upgrade"]
编辑用户 Migration 文件:
Schema::create('users', function (Blueprint $table) { $table->id(); $table->string('name'); $table->string('email')->unique(); $table->timestamp('email_verified_at')->nullable(); $table->string('password'); $table->boolean('is_admin'); $table->boolean('is_active'); $table->rememberToken(); $table->timestamps();});
编辑用户工厂 definition 方法:
//database\factories\UserFactory.phppublic function definition(){ return [ 'name' => fake()->name(), 'email' => fake()->unique()->safeEmail(), 'email_verified_at' => now(), 'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password 'remember_token' => Str::random(10), 'is_admin' => fake()->boolean(), 'is_active' => fake()->boolean(), ];}
编辑 DatabaseSeeder 的 run 方法:
//database\seeders\DatabaseSeeder.phppublic function run(){ \App\Models\User::factory(100)->create();}
编辑用户模型:
//app/Models/User.phpprotected $fillable = [ 'name', 'email', 'password', 'is_active', 'is_admin'];
运行 migrate 命令:
php artisan migrate --seed
添加 User Resource 和插件 Widget:
php artisan make:filament-resource User --simplephp artisan make:filament-widget UserOverview --resource=UserResource --stats-overview
编辑用户资源文件:
表单:
//app/Filament/Resources/UserResource.phppublic static function form(Form $form): Form{ return $form ->schema([ Forms\Components\TextInput::make('name') ->required() ->maxLength(255), Forms\Components\TextInput::make('email') ->email() ->required() ->maxLength(255), Forms\Components\Toggle::make('is_admin'), Forms\Components\Toggle::make('is_active'), ]);}
表格:
//app/Filament/Resources/UserResource.phppublic static function table(Table $table): Table{ return $table ->columns([ Tables\Columns\TextColumn::make('name'), Tables\Columns\TextColumn::make('email'), Tables\Columns\IconColumn::make('is_admin') ->boolean(), Tables\Columns\IconColumn::make('is_active') ->boolean(), Tables\Columns\TextColumn::make('created_at') ->date(), Tables\Columns\TextColumn::make('updated_at') ->date(), ]) ->filters([ Tables\Filters\TernaryFilter::make('is_admin'), Tables\Filters\TernaryFilter::make('is_active'), ]) ->actions([ Tables\Actions\EditAction::make(), Tables\Actions\DeleteAction::make(), ]) ->bulkActions([ Tables\Actions\DeleteBulkAction::make(), ]);}
添加 getWidgets 方法:
//app/Filament/Resources/UserResource.phpuse App\Filament\Resources\UserResource\Widgets\UserOverview;public static function getWidgets(): array{ return [ UserOverview::class, ];}
添加 getHeaderWidgets 方法:
//app/Filament/Resources/UserResource/Pages/ManageUsers.phpprotected function getHeaderWidgets(): array{ return [ UserOverview::class, ];}
你可以使用插件卡,在一个插件内展示许多许多不同的统计。编辑用户概览插件:
//app/Filament/Resources/UserResource/Widgets/UserOverview.phpclass UserOverview extends BaseWidget{ protected static ?string $pollingInterval = null; protected function getCards(): array { $usersCount = User::selectRaw(' COUNT(*) as total, SUM(CASE WHEN is_admin THEN 1 ELSE 0 END) AS admin, SUM(CASE WHEN is_active THEN 1 ELSE 0 END) AS active ')->first(); return [ Card::make('Total', $usersCount->total) ->color('primary') ->description('Total users'), Card::make('Admin', $usersCount->admin) ->color('danger') ->description('Admin users'), Card::make('Active', $usersCount->active) ->color('success') ->description('Active users'), ]; }}
到浏览器中查看用户资源。其中有三个头部插件:Total users, Admin users 及 Active users.
你可以在用户表中删除用户,表格里的数据更新了,但是这些插件里的信息不会更新。你需要手动刷新才能更新插件。
每个 Livewire 组件都有生命周期。生命周期狗子让你可以在组件生命周期的任意一个地方运行代码。我们可以使用 Updated 钩子,在 Livewire 组件更新后运行。
监听器是 key->value 键值对,key 是为监听的事件,值是组件上调用的方法。
我们可以使用 $refresh 魔术操作重新渲染组件。
在 UserOverviewWidget 文件中添加一个监听器:
//app/Filament/Resources/UserResource/Widgets/UserOverview.phpprotected $listeners = ['updateUserOverview' => '$refresh'];
updated 钩子方法提供了两个属性:
我们将使用 $name 属性监听两个表格事件:
然后,我们可以在 updated 方法使用这些名字以及触发 updateUserOverview 事件:
//app/Filament/Resources/UserResource/Pages/ManageUsers.phppublic function updated($name){ if (Str::of($name)->contains(['mountedTableAction', 'mountedTableBulkAction'])) { $this->emit('updateUserOverview'); }}
现在,每次删除操作点击后都会更新插件。
你可以检查表格事件,比如:
//text input in the top right of the tableif (Str::of($name)->contains('tableSearchQuery')) { ...} //the table filter formif (Str::of($name)->contains('tableFilters')) { ...}