Skip to content

故障排除

在 Livewire 总部,我们尽力在您遇到问题之前就将其消除。但是,有时候有些问题我们无法在不引入新问题的情况下解决,还有些时候有些问题我们无法预料到。

以下是您在 Livewire 应用中可能遇到的一些常见错误和场景。

组件不匹配

在与页面上的 Livewire 组件交互时,您可能会遇到奇怪的行为或如下错误消息:

Error: Component already initialized
Error: 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 :wire:key="$post->id" /> <!-- [tl! highlight] -->
@endforeach

但是,这里有一个您可能没有想到的棘手场景:

当您有一个 Livewire 组件深层嵌套在 @foreach 循环内时,您仍然需要为它添加 key。例如:

blade
@foreach($posts as $post)
    <div wire:key="{{ $post->id }}">
        ...
        <livewire:show-post :$post :wire:key="$post->id" /> <!-- [tl! highlight] -->
        ...
    </div>
@endforeach

如果没有在嵌套的 Livewire 组件上添加 key,Livewire 将无法在网络请求之间匹配循环的组件。

Key 前缀

另一个您可能遇到的棘手场景是在同一组件内有重复的 key。这通常是由于使用模型 ID 作为 key 导致的,有时可能会发生冲突。

以下是一个示例,我们需要添加 post-author- 前缀来将每组 key 指定为唯一的。否则,如果您有一个 $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 running
Alpine 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 包含了除 @alpinejs/ui 之外的所有 Alpine 插件。

缺少 @alpinejs/ui

Livewire 捆绑的 Alpine 版本包含除 @alpinejs/ui 之外的所有 Alpine 插件。如果您正在使用依赖此插件的 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>

注意:请确保包含此插件的最新版本,您可以在任何组件的文档页面上找到。