karlos3098 / laravel-primevue-table-service
通过引入简单的分页、过滤和排序功能,简化PrimeVue表格集成的服务。
README
作者: Let's Code IT - Karol Sójka
安装
安装包
composer require karlos3098/laravel-primevue-table-service
发布vue组件
php artisan vendor:publish --provider="Karlos3098\\LaravelPrimevueTableService\\Providers\\LaravelPrimevueTableServiceProvider"
警告
现在是最困难的一步,但非常重要
为了使我们的包正常工作,我们需要用PrimeVue中的DataTable.vue文件中的一个文件替换。这个文件对于每个Vue版本都不同。我们已经为PrimeVue版本准备了文件。
- 3.46.0
然后,使用列表中的适当版本,覆盖您app.js文件中DataTable组件的导入。
import DataTable from '@/karlos3098/laravel-primevue-table-service/src/Assets/PrimeVue/3.46.0/DataTable.vue';
现在,您还需要将这两个主要组件添加到app.js文件中。
import AdvanceTable from '@advance-table/Components/AdvanceTable.vue'; import AdvanceColumn from '@advance-table/Components/AdvanceColumn.vue';
别忘了初始化它们!
app .component('AdvanceTable', AdvanceTable) .component('AdvanceColumn', AdvanceColumn)
现在是时候创建第一个表格了。
我们建议使用Laravel中服务的方法。您的文件可能看起来像这样
<?php namespace App\Services; use App\Http\Resources\MessageResource; use App\Models\Message; use Illuminate\Http\Resources\Json\AnonymousResourceCollection; use Karlos3098\LaravelPrimevueTableService\Enum\TableCalendarDateFormat; use Karlos3098\LaravelPrimevueTableService\Services\BaseService; use Karlos3098\LaravelPrimevueTableService\Services\Columns\TableCalendarColumn; use Karlos3098\LaravelPrimevueTableService\Services\Columns\TableTextColumn; use Karlos3098\LaravelPrimevueTableService\Services\TableService; final class MessageService extends BaseService { public function __construct( protected Message $messageModel, ) { } /** * @throws \Exception */ public function findAll(): AnonymousResourceCollection { return $this->fetchData( MessageResource::class, $this->messageModel, new TableService( globalFilterColumns: ['text'], columns: [ 'text' => new TableTextColumn( placeholder: 'Search by text' ), 'contact' => new TableTextColumn( placeholder: 'Message contact name', queryPaths: [ 'senderPhoneNumber.phone_number', 'senderContact.name', 'receivers.phoneNumber.phone_number', 'receivers.contact.name', ], ), 'date' => new TableCalendarColumn( format: TableCalendarDateFormat::YMD, placeholder: 'Search by created at', sortable: true, queryPaths: ['created_at'], sortPath: 'created_at', ), 'type' => new TableDropdownColumn( placeholder: 'Select Message Type', options: [ new TableDropdownOptionTag( label: 'Incomming', query: fn ($query) => $query->where('incomming', true), severity: TagSeverity::SUCCESS ), new TableDropdownOptionTag( label: 'Outgoing', query: fn ($query) => $query->where('incomming', false), severity: TagSeverity::INFO ), ] ), ], rowsPerPage: [30, 100], propName: 'messages', ) ); } }
然后控制器可能如下所示
<?php namespace App\Http\Controllers; use App\Http\Controllers\Controller; use App\Services\MessageService; use Illuminate\Http\Request; use Inertia\Inertia; class MessageController extends Controller { public function __construct( protected MessageService $messageService, ) { } public function index() { return Inertia::render('Messages/Index', [ 'messages' => $this->messageService->findAll(), ]); } }
现在,我们需要在前端显示表格。
<script setup lang="ts"> import { MessageResource } from './MessageResource'; type Data = { data: MessageResource; }; </script> <template> <MessagesTemplate> <AdvanceTable prop-name="messages" > <template #header="{ globalFilterValue, globalFilterUpdated }"> <div class="flex justify-content-end"> <InputText :value="globalFilterValue" @update:model-value="globalFilterUpdated" placeholder="Search" /> </div> </template> <AdvanceColumn field="contact" style="min-width: 4rem"> <template #body="{ data }: Data"> <div class="flex align-items-center md:justify-content-start"> <img class="w-2rem h-2rem border-circle m-0" :src="data.first_receiver.phone_number.avatar" alt="" /> <div class="flex flex-column mx-3"> <span class="block text-900 font-semibold">{{ data.first_receiver.phone_number.name }}</span> </div> </div> </template> </AdvanceColumn> <AdvanceColumn field="text"></AdvanceColumn> <AdvanceColumn field="date" dataType="date"> <template #body="{ data }: Data"> <div :style="{ minWidth: '10rem' }"> <div class="flex justify-content-end w-full px-0"> <span ref="dateRef" class="date-text text-700 font-semibold white-space-nowrap"> {{ data.created_at }} </span> </div> </div> </template> </AdvanceColumn> <AdvanceColumn field="type"></AdvanceColumn> </AdvanceTable> </MessagesTemplate> </template>
让我们从'globalFilterColumns'开始。这是一个列表,在表格头模板中,全局搜索引擎应该在这些字段中搜索。
在上面的例子中,我们显示了3列,这些列是我们管理的
- 联系
- 文本
- 日期
最简单的例子是文本列。这是一个常规的文本列,我们可以简单地通过短语搜索。
第二个有趣的是'联系'。这个名称既不用于资源,也不作为模型中的字段。这是Vue和后端之间的正确名称。'queryPaths'在这里很重要。我们可以提供一个字段列表(如您所见,也包括关系),过滤应在这些字段上执行。如果没有提供,网站将自动尝试在不存在的'联系'列中搜索。
另一个例子是'日期'列。在这种情况下,我将其声明为'created_at'列,并在此处进行过滤,但我们也有排序。
最后一个例子是'type',我们可以通过从列表中选择选项来搜索。
在列声明下,您还会找到'rowsPerPage'。它告诉您表格中每页可用的分页数。
还要记得提供正确的'propName',即您在inertiajs中传递表格的prop。如果名称不正确,则排序和分页不会有反应。
总结
该项目旨在应用于我自己的多个项目中,但我决定分享它。我愿意合作并扩展它。在不久的将来,我也想使用PrimeVue提供的数字范围进行一些过滤,但我没有时间。
为了让项目工作,我必须在DataTable.vue文件中替换一个导入,但DataTable的每个版本都不同。
尽管如此,我提供的这个解决方案将从3.46版开始,以及大约十多个版本向上工作,但您可能需要将其他版本放入项目中以便方便。