team-nifty-gmbh/tall-datatables

一个使用 alpinejs、tailwind、livewire 和 laravel 创建 datatables 的包


README

Latest Version on Packagist GitHub Tests Action Status GitHub Code Style Action Status Total Downloads

此包旨在通过 alpinejs、tailwind、livewire 和 laravel 提供一种简单的方式来创建 datatables。

它主要依赖于 alpinejs 来避免在发生变化时重新渲染整个表格。

img_1.png

要求

  • PHP >= 8.1
  • Laravel >= 9.46
  • AlpineJS >= 3.0
  • TailwindCSS >= 3.0
  • Livewire >= 2.11
  • Vite >= 4.0
  • MeiliSearch >= 1.0

安装

  1. 您可以通过 composer 安装此包
composer require team-nifty-gmbh/tall-datatables
  1. 将脚本标签添加到您的布局中,在 alpinejs 之前
...
<livewire:scripts/>

<wireui:scripts />
@dataTablesScripts

@vite(['resources/js/alpine.js'])
...

请注意,从步骤 2 开始遵循 wireui 安装说明: https://livewire-wireui.com/docs/get-started

  1. 将以下内容添加到您的 tailwind.config.js 中
module.exports = {
    presets: [
        ...
        require('./vendor/team-nifty-gmbh/tall-datatables/tailwind.config.js')
    ],
    content: [
        ...
        './vendor/team-nifty-gmbh/tall-datatables/resources/views/**/*.blade.php',
        './vendor/team-nifty-gmbh/tall-datatables/resources/js/**/*.js',
    ],
    ...
}
  1. 运行 vite build 以编译 JavaScript 和 CSS 文件
vite build
  1. 发布视图是可选的。如果您想使用默认视图,可以跳过此步骤。

可选地,您可以使用以下命令发布和运行迁移

php artisan vendor:publish --tag="tall-datatables-migrations"
php artisan migrate

可选地,您可以使用以下命令发布配置文件

php artisan vendor:publish --tag="tall-datatables-config"

可选地,您可以使用以下命令发布视图

php artisan vendor:publish --tag="tall-datatables-views"

配置

默认情况下,该包将表的状态缓存在会话中。如果您想禁用此功能,可以在 .env 文件中将 cache 选项设置为 false。

TALL_DATATABLES_CACHE=false

缓存是按表格进行的。如果您想在不同的上下文中使用您的表格,应该设置不同的缓存键。在您的 blade 文件中,将缓存键传递给组件。

<livewire:data-tables.user-data-table :cache-key="profile.subusers.user-table" />

您必须确保您在应用程序中设置的所有缓存键都是唯一的。

用法

此命令创建一个新的 DataTable 类。

php artisan make:data-table UserDataTable "App\Models\User"

在此类中,您应该定义至少要显示的列

public array $enabledCols = [
    'id',
    'name',
    'email',
    'email_verified_at',
    'created_at',
    'updated_at',
];

选择布局

默认情况下,表格以表格的形式渲染。您可以通过重写 getLayout 方法来更改布局。

public function getLayout(): string
{
    return 'tall-datatables::layouts.grid';
}

此包提供两个布局:'tall-datatables::layouts.grid' 和 'tall-datatables::layouts.table'

您也可以在 resources/views/components 文件夹内创建一个 blade 文件来创建自己的布局。

grid_layout.png

使用您自己的视图

如果您想使用您自己的视图作为布局的包装器,可以重写 $view 属性。

protected string $view = 'data-tables.my-custom-view';

您的视图应包含默认的数据表包装器

<div>
    <!-- your custom stuff like modals -->
    <div>
        hey i'm rendered above the table
    </div>
    @include('tall-datatables::livewire.data-table')
</div>

向表格中添加按钮

您可以通过重写 getTableActions 方法向表格中添加按钮。请参阅 WireUi 文档了解可用选项。

这些按钮将在表格上方右侧渲染。如果您的表格启用了搜索,则按钮将在搜索输入的右侧渲染。

注意: 我建议将表格嵌入到另一个组件中,并使用 wire:ignore 指令来避免重新渲染整个页面。“创建”按钮可以向父组件派发一个 alpinejs 事件。监听器可以触发 livewire 函数来渲染创建表单。

use TeamNiftyGmbH\DataTable\Htmlables\DataTableButton;

...

public function getTableActions(): array
{
    return [
        DataTableButton::make()
            ->label('Create')
            ->icon('plus')
            ->color('primary')
            ->attributes([
                'x-on:click' => '$dispatch(\'create-user\')',
            ]),
    ];
}

向行中添加按钮

注意: 请记住,tall-datatables 依赖于 alpinejs 来渲染数据。

每一行都是使用 x-for 指令渲染的。这意味着每个记录都作为一个名为 record 的变量可用。

请记住,记录变量仅包含由 getReturnKeys php 方法返回的列。模型键始终可用。

您可以通过覆盖 getRowActions 方法向行中添加按钮。请查看 WireUi 文档以获取可用选项。

use TeamNiftyGmbH\DataTable\Htmlables\DataTableButton;

...

public function getRowActions(): array
{
    return [
        \TeamNiftyGmbH\DataTable\Htmlables\DataTableButton::make()
            ->label('Edit')
            ->icon('eye')
            ->color('primary')
            ->attributes([
                'x-on:click' => '$wire.edit(record.id)',
                'x-bind:class' => 'record.is_locked ? \'hidden\' : \'\''
            ]),
        \TeamNiftyGmbH\DataTable\Htmlables\DataTableButton::make()
            ->label('Delete')
            ->icon('trash')
            ->color('negative'),
    ];
}

提示:如果您想在按钮点击时防止派发行点击事件,请将 $event.stopPropagation() 方法添加到按钮属性中。

DataTableButton::make()
   ->label('Edit')
   ->icon('pencil')
   ->color('primary')
   ->attributes([
       'x-on:click' => '$wire.edit(record.id); $event.stopPropagation()', // <--- here
     ]),

合并列

您可以通过覆盖 get{Position}Appends 将多个列合并为一个。如名称所示,定义的列将被追加到该位置。

public function getBottomAppends(): array
{
    return [
        'name' => 'email',
    ];
}

public function getLeftAppends(): array
{
    return [
        'name' => 'avatar',
    ];
}

此功能将在名称列下方追加电子邮件。这只是为了查看目的。数据仍然在记录变量中。此外,所有格式化器在列追加之前都会应用。

注意:请记住将追加的列添加到 getReturnKeys 方法中。

预加载

如果您需要预加载其他数据,可以覆盖 getBuilder 方法

protected function getBuilder(Builder $builder): Builder
{
    return $builder->with('roles');
}

最小化网络流量

数据表组件将仅返回您在 enabledCols 属性中定义的列。如果您需要始终返回特定列,则可以覆盖 getReturnKeys 方法。

这特别适用于您想在前端格式化货币值时。

protected function getReturnKeys(): array
{
    return array_merge(parent::getReturnKeys(), ['currency.iso']);
}

在另一个组件中使用您的数据表

要使用此新的数据表,您可以在 blade 文件中添加 livewire 标签

<livewire:data-tables.user-data-table />

您可以通过以下方式调用组件时传递上下文属性

<livewire:data-tables.user-data-table 
    :searchable="false" 
    :filters="[['is_active' => true]]" 
/>

这使您的组件可重用,并且您可以在不同的上下文中使用它。

将您的数据表用作全页组件

要将此新的数据表用作全页组件,只需将路由指向组件即可。有关更多信息,请参阅 Livewire 文档

Route::get('/users', \App\Http\Livewire\DataTables\UserDataTable::class);

行点击

注意:始终派发 data-table-row-clicked 事件,但如果您的记录实现了 InteractsWithDataTables 接口,则将调用 getUrl() 方法以获取要重定向到的 URL。

如果您只需要点击事件而不进行重定向,可以将 $hasNoRedirect 属性设置为 true。

public function getUrl(): string
{
    return route('users.show', $this->id);
}

每次行点击都会派发一个带有模型作为有效负载的 data-table-row-clicked 事件。您可以在 AlpineJS 中监听此事件。

<div x-data="{ ... }" x-on:data-table-row-clicked="console.log($event.detail)">
    <livewire:data-tables.user-data-table />
</div>

如果您想使用您的点击行与 livewire,我建议您使用 alpinejs 中的 $wire 属性。

<div x-data="{ ... }" x-on:data-table-row-clicked="$wire.set('user', $event.detail)">
    <livewire:data-tables.user-data-table />
</div>

Echo 和 Eloquent 事件

如果您想监听在模型上发生的 Eloquent 事件,您可以在您的 Datatable 中使用 HasEloquentListeners 特性。此特性将自动注册 createdupdateddeleted 事件的 Echo 事件监听器。

您的模型应使用此包中的 BroadcastsEvents 特性。

use TeamNiftyGmbH\DataTable\Traits\BroadcastsEvents;

class User extends Authenticatable
{
    use BroadcastsEvents;
}

您必须按如下方式定义您的身份验证回调

Broadcast::channel(App\Models\User::class, function ($user, $id) {
    return $user->id === (int) $id;
});

要使 created 事件正常工作,您必须添加一个额外的路由

Broadcast::channel(\App\Models\User::getBroadcastChannel(), function ($user) {
    return true;
});

准备您的模型

HasFrontendFormatter 特性

如果您想为前端格式化数据,您应该在您的模型中使用 HasFrontendAttributes 特性。此特性将在您的模型中添加一个名为 getFrontendAttributes() 的方法。

此外,您应该在模型中定义一个 detailRouteName 属性,该属性指向显示模型详细信息的视图。

use TeamNifty\TallDatatables\Traits\HasFrontendAttributes;

class User extends Authenticatable
{
    use HasFrontendAttributes;
    
    protected string $detailRouteName = 'users.id';
    ...
}

如果您的详细路由需要其他参数,您可以在模型类中覆盖 getDetailRouteParameters() 方法。

public function getDetailRouteParameters(): array
{
    return [
        'id' => $this->id,
        'foo' => 'bar',
    ];
}

此特性为您的模型添加了一个属性访问器,该访问器包含单个模型实例的详细路由。

$user = User::first();
$user->href; // returns the detail route for the user

美化表格

向行添加属性

您可以通过覆盖 getRowAttributes 方法向行添加属性。

use TeamNiftyGmbH\DataTable\Htmlables\DataTableRowAttributes;

...

public function getRowAttributes(): array
{
    return DataTableRowAttributes::make()
        ->bind('class', 'record.is_active ? \'bg-green-100\' : \'bg-red-100\'')
        ->on('click', 'alert($event.detail.record.id)')
        ->class('cursor-pointer')
}

无限滚动

默认情况下,表格显示分页。如果您想使用无限滚动,可以将 hasInfiniteScroll 属性设置为 true。

public bool $hasInfiniteScroll = true;

当表格的末尾进入视口时,表格将添加您在 perPage 属性中定义的记录数量。请注意,随着 Livewire 需要加载数据而不是仅添加新记录,网络流量每次都会增加。

注意:如果您使用无限滚动,需要在主项目的 js 文件中导入 alpinejs intersect 插件。

import Alpine from 'alpinejs';
import intersect from '@alpinejs/intersect';

Alpine.plugin(intersect);

window.Alpine = Alpine;

Alpine.start();

在列名下方显示筛选输入框

如果您想在列名下方显示筛选输入框,可以将 showFilterInputs 属性设置为 true。

public bool $showFilterInputs = true;

隐藏表头

如果您想隐藏表头,可以将 hasHeader 属性设置为 false。

public bool $hasHeader = false;

带有筛选器的侧边栏仍然可用,但您必须添加自己的按钮来显示它。

图标

您可以在模型中设置一个 iconName 属性,它将被用于在表格中显示一个图标。您可以使用来自 heroicons 库的任何图标。

protected string $iconName = 'user';

InteractsWithDataTables 接口

如果模型在一个具有表格的模型的关联中使用,您应该实现 TeamNifty\TallDatatables\Contracts\InteractsWithDataTables 接口。此接口将为您的模型添加两个方法。

use TeamNifty\TallDatatables\Contracts\InteractsWithDataTables;

class User extends Authenticatable implements InteractsWithDataTables
{
    ...
    
    public function getLabel(): string
    {
        return $this->name;
    }
    
    public function getDescription(): string
    {
        return $this->email;
    }
}

类型转换

该包使用类型转换来格式化前端的数据。您可以在模型的 casts 属性中定义自己的类型转换。除了原始类型转换外,您还可以添加自己的类型转换。这些类型转换类应该实现 TeamNifty\TallDatatables\Contracts\HasFrontendFormatter 接口,该接口提供了 getFrontendFormatter() 方法。

use TeamNifty\TallDatatables\Casts\Date;

可搜索

如果您想在表格中搜索,应使用 Laravel Scout 的可搜索特性。该包将自动检测您的模型是否可搜索,并将搜索输入添加到表格中。

如果您不想使用搜索输入,可以在您的 DataTable 中将 isSearchable 属性设置为 false。

public bool $isSearchable = false;

测试

composer test

变更日志

请参阅 变更日志 了解最近更改的详细信息。

贡献

请参阅 贡献指南 了解详细信息。

安全漏洞

请参阅 我们的安全策略 了解如何报告安全漏洞。

致谢

许可

MIT 许可证 (MIT)。请参阅 许可文件 了解更多信息。