Laravel Livewire:14 个提示和技巧
发布日期 作者 PovilasKorop
Laravel Livewire 是一个很棒的工具,可以实现页面上的动态行为,而无需直接编写 JavaScript 代码。而且,像任何工具一样,它有很多“隐藏的宝石”,既包括在它的官方文档中,也包括开发人员提供的实用的额外技巧。我决定在这篇文章中整理一些。让我们开始吧!
1. 不需要 render()
典型的 render()
方法看起来像这样
// app/Http/Livewire/PostsShow.phpclass PostsShow extends Component{ public function render() { return view('livewire.posts-show'); }}
但是,如果你的 render()
方法只是一行代码来渲染**默认**视图,你可以从组件中删除该 render()
方法,它仍然可以工作,加载来自供应商方法的默认 render()
。
class PostsShow extends Component{ // This empty component will still work and load the Blade file}
2. 子文件夹中的组件
如果你想在子文件夹中生成组件,例如 app/Http/Livewire/Folder/Component.php
,你有两种方法可以做到
php artisan make:livewire Folder/Component
或者
php artisan make:livewire folder.component
请注意,第一种方法使用第一个字母大写,第二种方法使用小写。在这两种情况下,都会生成两个文件
- app/Http/Livewire/Folder/Component.php
- resources/views/livewire/folder/component.blade.php
如果子文件夹不存在,它们会自动创建。
3. 非默认文件夹中的组件
如果你使用带有 Livewire 组件的外部包,你可能在与默认 app/Http/Livewire
不同的文件夹中拥有 Livewire 组件。然后,你可能需要将其名称绑定到实际位置。
通常,它是在 app/Providers/AppServiceProvider.php
(或任何服务提供者)方法 boot()
中完成的
class AppServiceProvider extends ServiceProvider{ public function boot() { Livewire::component('shopping-cart', \Modules\Shop\Http\Livewire\Cart::class); }}
4. 轻松重命名或移动组件
如果你在使用 make:livewire
生成组件时拼错了,不用担心。你不需要手动重命名两个文件,有一个命令可以做到这一点。
例如,如果你写了 php artisan make:livewire Prduct
,但实际上你想要“Product”,并且还决定将其放入子文件夹,你可以使用以下命令进行操作
php artisan livewire:move Prduct Products/Show
结果将是
COMPONENT MOVED CLASS: app/Http/Livewire/Prduct.php => app/Http/Livewire/Products/Show.phpVIEW: resources/views/livewire/prduct.blade.php => resources/views/livewire/products/show.blade.php
5. 更改默认组件模板
Livewire 组件使用默认模板(即“存根”)生成。它们隐藏在 Livewire 包的“vendor”文件夹中,但你可以发布它们并根据需要进行编辑。
运行此命令
php artisan livewire:stubs
你会发现一个新的文件夹 /stubs
,里面有一些文件。
stubs/livewire.stub
的示例
<?php namespace [namespace]; use Livewire\Component; class [class] extends Component{ public function render() { return view('[view]'); }}
例如,如果你想在没有 render()
方法的情况下生成组件,只需从存根文件中删除它,然后每次运行 php artisan make:livewire Component
时,它都会从你更新的公共存根中获取模板。
6. 不要仅仅为了设置值而创建方法
如果你有一个点击事件,它会设置某个属性的值,你可能会这样做
<button wire:click="showText">Show</button>
然后
class Show extends Component{ public $showText = false; public function showText() { $this->showText = true; }}
但实际上,你可以直接从 Blade 文件中将新值分配给 Livewire 属性,而无需在 Livewire 组件中使用单独的方法。
这是代码
<button wire:click="$set('showText', true)">Show</button>
所以,你调用 $set
并提供两个参数:你的属性名称和新值。
7. 更进一步:轻松设置 True/False 值
接着上一个提示,如果你的属性是布尔变量,具有 true/false 值,并且你想要一个显示/隐藏按钮,你可以这样做
<button wire:click="$toggle('showText')">Show/Hide</button>
注意:我个人会避免使用 Livewire 来实现这种简单的切换效果,因为它会向服务器添加额外的请求。
相反,最好使用 JavaScript 来实现,例如 Alpine.js
<div x-data="{ open: false }"> <button @click="open = true">Expand</button> <span x-show="open"> Content... </span></div>
8. 三种减少服务器请求的方法
Livewire 的主要批评之一是它对服务器进行了太多请求。如果你在输入字段上使用 wire:model
,每次按键都可能会调用服务器来重新渲染组件。如果你有一些实时效果,例如“实时搜索”,这非常方便。但总的来说,服务器请求可能相当昂贵,在性能方面。
但是,自定义 wire:model
的行为非常容易。
-
wire:model.debounce
:默认情况下,Livewire 在输入按键后等待 150 毫秒,然后执行服务器请求。但你可以覆盖它:<input type="text" wire:model.debounce.1000ms="propertyName">
-
wire:model.lazy
:默认情况下,Livewire 会监听输入上的**所有**事件,然后执行服务器请求。通过提供lazy
指令,你告诉 Livewire 只监听change
事件。这意味着用户可以继续输入和更改值,只有当用户点击该字段之外时,才会触发服务器请求。 -
wire:model.defer
:这不会在输入更改时触发服务器请求。它会将新值保存在内部,并在下一个网络请求(可能来自其他输入字段或其他按钮点击)中传递它。
9. 自定义验证属性
Livewire 验证与 Laravel 验证引擎非常相似,但有一些区别。在 Laravel 中,如果你想自定义属性的名称,你可以在 Form Request 类中定义 attributes()
方法。
在 Livewire 中,方法不同。在组件中,你需要定义一个名为 $validationAttributes
的属性,并将键值数组分配给它
class ContactForm extends Component{ protected $validationAttributes = [ 'email' => 'email address' ]; // ...
这对常见的错误消息很有用,例如“字段 [XYZ] 是必需的”。默认情况下,XYZ 会替换为字段名称,这可能不是一个友好的单词,因此用更清晰的内容替换它来显示错误消息是值得的。
10. 加载指示器
在官方文档中描述过,但我看到很少使用它。如果屏幕上的某些操作需要一段时间,最好显示一些加载指示器,例如旋转的 gif,或者只是一个“正在加载数据...”的文本。
在 Livewire 中,实现它并进行自定义非常容易。
最简单的处理数据示例:当发出服务器请求时,它会显示“正在处理付款...”文本,直到服务器请求完成并返回结果。
<div> <button wire:click="checkout">Checkout</button> <div wire:loading> Processing Payment... </div></div>
在实践中,我喜欢只在需要一段时间时才显示这样的加载指示器。在所有可能的情况下,每次重新渲染 DOM 都没有意义。如果请求花费的时间超过 500 毫秒,我们只这样做怎么样?
很简单
<div wire:loading.delay.longer>...</div>
还可以使用 CSS 类来控制加载状态,将它们与特定操作相关联,以及更多功能:阅读 官方文档了解详情。
11. 离线指示器
Livewire 的另一个已记录但鲜为人知的特性是告知用户他们的互联网连接是否已断开。如果您的应用程序使用实时数据或屏幕上的多次更新,这将非常有用:您可以模糊网页的某些部分并显示“离线”文本。
操作起来非常简单
<div wire:offline> You are now offline.</div>
此外,如我所述,您可以通过分配 CSS 类来模糊某些元素,如下所示
<div wire:offline.class="bg-red-300"></div>
12. 使用 Bootstrap 框架进行分页
与 Laravel 类似,Livewire 默认情况下使用 Tailwind 框架的分页样式。幸运的是,它很容易覆盖,只需为属性提供不同的值即可
class ShowPosts extends Component{ use WithPagination; protected $paginationTheme = 'bootstrap';
您可以在 Livewire Github 存储库中直接查看可用的分页设计。在浏览时,我没有找到有关使用 Bootstrap 4 或 Bootstrap 5 版本的任何信息。
13. 无挂载:自动路由模型绑定
如果您想将对象传递给 Livewire 组件,这是使用 mount()
方法的典型方法
class ShowPost extends Component{ public $post; public function mount(Post $post) { $this->post = $post; }}
然后,在 Blade 中的某个位置,您有 @livewire('show-post', $post)
。
但您是否知道,如果您为 Livewire 属性提供类型提示,路由模型绑定会自动发生?
class ShowPost extends Component{ public Post $post;}
就是这样,根本不需要 mount()
方法。
14. 删除确认模态框
如果您有一个“删除”按钮,并且希望在执行操作之前调用确认 JavaScript 模态框,此代码在 Livewire 中将无法正常工作
<button wire:click="delete($post->id)" onclick="return confirm('Are you sure?')">Delete</button>
为此,有一些可能的解决方案,也许最优雅的是在 Livewire 事件发生之前停止它
<button onclick="confirm('Are you sure?') || event.stopImmediatePropagation()" wire:click="delete($post->id)">Delete</button>
如果确认结果为假,则 event.stopImmediatePropagation()
将阻止调用 Livewire 方法。
您可以在 这个 Github 问题讨论中找到一些其他可能的解决方案。
就是这样,Livewire 的鲜为人知的功能和一些小技巧。希望对您有所帮助!