主题
在 Livewire 总部,我们尝试在您遇到问题之前就将其从您的道路上移除。然而,有时我们无法在不引入新问题的情况下解决某些问题,而其他时候,有些问题是我们无法预见的。
以下是您在 Livewire 应用程序中可能遇到的一些常见错误和场景。
组件不匹配
当与页面上的 Livewire 组件交互时,您可能会遇到奇怪的行为或以下类似的错误消息:
Error: Component already initializedError: Snapshot missing on Livewire component with id: ...您可能遇到这些消息的原因有很多,但最常见的原因是忘记在 @foreach 循环内的元素和组件上添加 wire:key。
添加 wire:key
每当您在 Blade 模板中使用 @foreach 等循环时,您需要在循环内第一个元素的开始标签上添加 wire:key:
blade
@foreach($posts as $post)
<div wire:key="{{ $post->id }}"> <!-- [tl! highlight] -->
...
</div>
@endforeach这确保当循环变化时,Livewire 可以跟踪循环中的不同元素。
同样的规则适用于循环内的 Livewire 组件:
blade
@foreach($posts as $post)
<livewire:show-post :$post :key="$post->id" /> <!-- [tl! highlight] -->
@endforeach然而,这里有一个您可能没有想到的微妙场景:
当您在 @foreach 循环内有一个深度嵌套的 Livewire 组件时,您仍然需要为其添加键。例如:
blade
@foreach($posts as $post)
<div wire:key="{{ $post->id }}">
...
<livewire:show-post :$post :key="$post->id" /> <!-- [tl! highlight] -->
...
</div>
@endforeach如果嵌套的 Livewire 组件上没有键,Livewire 将无法在网络请求之间匹配循环组件。
添加键前缀
您可能遇到的另一个微妙场景是在同一组件内有重复的键。这通常是由于使用模型 ID 作为键导致的,这有时会冲突。
以下是一个示例,我们需要添加 post- 和 author- 前缀来将每组键指定为唯一。否则,如果您有一个 $post 和 $author 模型具有相同的 ID,就会发生 ID 冲突:
blade
<div>
@foreach($posts as $post)
<div wire:key="post-{{ $post->id }}">...</div> <!-- [tl! highlight] -->
@endforeach
@foreach($authors as $author)
<div wire:key="author-{{ $author->id }}">...</div> <!-- [tl! highlight] -->
@endforeach
</div>Alpine 的多个实例
安装 Livewire 时,您可能会遇到以下类似的错误消息:
Error: Detected multiple instances of Alpine runningAlpine Expression Error: $wire is not defined如果是这种情况,您可能在同一页面上运行了两个版本的 Alpine。Livewire 在幕后包含了自己的 Alpine 捆绑包,因此您必须删除应用程序中 Livewire 页面上的任何其他 Alpine 版本。
发生这种情况的一个常见场景是将 Livewire 添加到已经包含 Alpine 的现有应用程序中。例如,如果您安装了 Laravel Breeze 启动套件然后添加了 Livewire,就会遇到这种情况。
解决方法很简单:删除额外的 Alpine 实例。
删除 Laravel Breeze 的 Alpine
如果您在现有的 Laravel Breeze(Blade + Alpine 版本)中安装 Livewire,您需要从 resources/js/app.js 中删除以下行:
js
import './bootstrap';
import Alpine from 'alpinejs'; // [tl! remove:4]
window.Alpine = Alpine;
Alpine.start();删除 CDN 版本的 Alpine
由于 Livewire 版本 2 及以下默认不包含 Alpine,您可能在布局的 head 中包含了 Alpine CDN 作为 script 标签。在 Livewire v3 中,您可以完全删除此 CDN,Livewire 将自动为您提供 Alpine:
html
...
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script> <!-- [tl! remove] -->
</head>注意:您还可以删除任何额外的 Alpine 插件,因为 Livewire 包含所有 Alpine 插件,除了 @alpinejs/ui。
缺少 @alpinejs/ui
Livewire 捆绑的 Alpine 版本包含所有 Alpine 插件,除了 @alpinejs/ui。如果您使用来自 Alpine Components 的无头组件(依赖于此插件),您可能会遇到以下类似的错误:
Uncaught Alpine: no element provided to x-anchor要修复此问题,您可以在布局文件中将 @alpinejs/ui 插件作为 CDN 包含进来,如下所示:
html
...
<script defer src="https://unpkg.com/@alpinejs/ui@3.13.7-beta.0/dist/cdn.min.js"></script> <!-- [tl! add] -->
</head>注意:请务必包含此插件的最新版本,您可以在任何组件的文档页面上找到它。