[黑科技] 使用 Laravel Livewire 来构建实时搜索功能(不使用一行 JS 代码)

Laravel

最终结果-完全交互式搜索和分页,无需Javascript

对于关注 Laracon 2019年的人来说,你们可能已经看到了来自Caleb Porzio被称为Livewire.的令人惊叹的新套餐。正如他的网站上所描述的那样:

livewire是一个针对Laravel的全栈框架,它使构建动态前端变得像编写普通PHP一样简单(从字面上看)。

我两年前开始使用Laravel,我最大的挑战之一就是构建互动页面。Laravel让我很容易跳入Web开发,但我发现跳到使用Vue.js或Reaction太令人困惑,总是导致另一层复杂性。当Caleb展示他的简单计数器时,我立即认为Livewire将是搜索的理想选择。我已经在下面概述了如何使用Livewire通过分页交互式搜索雄辩的记录。

设置 Livewire (文档)

composer require calebporzio/livewire

将其包含在你要搜索的所有页面结束正文标签之前:

@livewireAssets </body> 
</html>

Livewire 的工作原理是将前端 Livewire 组件中的数据直接连接到后端 Livewire 控制器。然后,这些控制器可以重新呈现组件,而不需要重新加载整个页面。我们的目标是将搜索查询从输入表单传递到后端,然后使用它来搜索我们的 Eloquent 模型。每次搜索将更新页面上显示的数据!

填充数据库 (选做)

在此示例中使用的是全新的 Laravel 应用程序。如果你使用的是现成的应用程序,可以跳过这一步,但是为了有一些数据来搜索,你可以用 Laravel 的默认用户工厂类来填充用户表。将以下代码添加到您的DatabaseSeeder.php文件:

然后运行 php artisan db:seed, 你将有500个用户可以搜索!

创建搜索组件

首先,让我们创建搜索控制器和 Livewire 视图:

php artisan make:livewire search

这将在 App\Http\Livewire 下创建一个新的名称为 Search.php 的「控制器」。 它还会在 Livewire views 文件夹中创建一个名为 search.blade.php的视图文件。

创建搜索框 + 公共变量

让我们从 search.blade.php 开始,添加一个输入表单并绑定到 Livewire:

<input type="text" wire:model="searchTerm" />

通过设置 wire:model="searchTerm" Livewire 将自动更新 Search.php 控制器中名为 $searchTerm 的公共变量。 现在我们来添加一下:

我把它包含在默认的 Laravel 主页上,但是你可以把它添加到任何你喜欢的页面上。 只需要在 blade 文件中添加 @livewire('search') 就可以了。 这是我们现在得到的:

显示 Eloquent 记录

首先将所有用户传递给组件,并在一个简单的列表中显示它们(尚未进行搜索)。 因为我们要使它具有交互性,所以需要在 search.blade.php 文件中完成这些操作。 只需创建另一个名为 $users 的公共变量,并设置其值为 User:: all()

现在当页面渲染时,它将向搜索视图传递一个名为 $users 的变量。 我们可以像平常一样使用 Blade,循环遍历所有用户:

现在我们看到所有的用户:

搜索 Eloquent

为了得到我们想要的结果,我们希望根据用户搜索的内容过滤列表数据。 与直接将 User::all() 返回到页面不同,我们将使用 SQL 的内置 ilike 子句来搜索数据库以匹配记录。 因为有些用户可能只搜索姓名或中间名,所以我们可以在搜索关键词周围使用 % 号,表示关键词两边的任意数量的字符。 所有这些实现加起来是这样的:

就是这样! 打开网页,我们现在可以立即搜索所有的结果。 不用写一行 Javascript 代码!

使用 Livewire 的全交互式搜索组件


如何分页?

我们的一些用户有数百页的内容,我们需要一个简单的方法来交互式搜索和对所有的结果分页。 下面的步骤将使用Livewire 配合 Laravel 的默认分页。

分页 + 显示

首先,添加默认分页链接 {{$users->onEachSide(1)->links()}}search.blade.php来显示分页。 为了使用 Eloquent 分页, 则需要更新查询语句为: $this->users = User::where('name', 'ilike', $searchTerm)->paginate(10);

分页链接现在出来了,并且实际有效! 但是,您可能会注意到,每次点击都会重新加载整个页面,当尝试搜索和切换页面时,它会抛出一个错误。 我们需要更新默认的分页视图来使用 Livewire,让它不会重新加载整个页面。

创建自定义分页

与其构建一个全新的分页系统,不如使用默认的分页系统并使用新的 Livewire 功能对其进行修改。可以在 resources/views/vendor/pagination/找到默认的 Bootstrap 分页 作为 bootstrap-4.blade.php。我们可以看到每个按钮和页码都是设置为上一个或下一个URL的链接:

让我们复制整个文件并创建一个名为 livewire-pagination.blade.php 的新自定义分页视图。然后删除整个文档中的所有 href=”url” 链接(应该有三个),并将它们设置成 href=”#”,以使页面不会重新加载。最后给每个链接添加一个 Livewire click 的方法

wire:click="setPage('{{$paginator->previousPageURL()}}')"

更新后的分页看起来像这样:

我们还需要使用新方法 setPage(url) 更新我们的控制器:

要显示此自定义的分页,我们可以通过向 links 函数传递路径直接在 blade 视图模板中链接到它:

{{$users->onEachSide(1)->links('livewire-pagination')}}

在 Controller 中更新分页

现在,我们需要一种方法来基于所选的当前页面来更新分页结果和组件。Laravel 的 Paginator 自带了 currentPageResolver() 方法使我们可以预先设置要展示的页面。我们可以将当前页码传递给此方法,它将自动更新结果。

为了获得选定的页码,我们需要将传递到 setPage($url)方法中的 url 分开。我们还必须声明一个公共的 $currentPage。看起来像这样:

现在只要单击分页按钮,结果就会更新以显示正确的页面。当用户搜索时,他们的结果也将被分页,并且每次搜索时分页都将重置以避免混淆:

Laravel


希望这会对你有所帮助!我计划继续进行此工作,因此请让我知道任何想法/问题。您可以在Twitter上关注我@branickweix

本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

原文地址:https://medium.com/@branick/search-with-...

译文地址:https://learnku.com/laravel/t/40775

本帖已被设为精华帖!
本文为协同翻译文章,如您发现瑕疵请点击「改进」按钮提交优化建议
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 7

太方便了 ,下次构建搜索web页面时直接整上

4年前 评论
十里长亭

感谢楼主

4年前 评论

能不能做删除,新增

3年前 评论

真心方便了,好东西阿!

3年前 评论

经过多日研究总结出这篇文章无法在laravel8中使用!

3年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!