Skip to content

@island

@island 指令用于在组件内创建独立更新的隔离区域,无需重新渲染整个组件。

基本用法

@island 包裹模板的任意部分来创建隔离区域:

blade
<?php // resources/views/components/⚡dashboard.blade.php

use Livewire\Attributes\Computed;
use Livewire\Component;
use App\Models\Revenue;

new class extends Component {
    #[Computed]
    public function revenue()
    {
        // 昂贵的计算...
        return Revenue::yearToDate();
    }
};
?>

<div>
    @island
        <div>
            收入: {{ $this->revenue }}

            <button type="button" wire:click="$refresh">刷新</button>
        </div>
    @endisland

    <div>
        <!-- 其他内容... -->
    </div>
</div>

当点击"刷新"按钮时,只有 island 会重新渲染——组件的其余部分保持不变。

延迟加载 Islands

使用 lazy 参数,将 island 的初始渲染延迟到页面加载之后:

blade
@island(lazy: true)
    <div>
        收入: {{ $this->revenue }}
    </div>
@endisland

Island 最初显示加载状态,然后通过单独的请求获取内容。

Lazy 与 Defer 的区别

默认情况下,lazy 会等到 island 在视口中可见时才加载。使用 defer 则在页面加载后立即加载:

blade
{{-- 滚动到视口时加载 --}}
@island(lazy: true)
    <!-- ... -->
@endisland

{{-- 页面加载后立即加载 --}}
@island(defer: true)
    <!-- ... -->
@endisland

自定义加载状态

使用 @placeholder 自定义加载时显示的内容:

blade
@island(lazy: true)
    @placeholder
        <div class="animate-pulse">
            <div class="h-32 bg-gray-200 rounded"></div>
        </div>
    @endplaceholder

    <div>
        收入: {{ $this->revenue }}
    </div>
@endisland

命名 Islands

为 islands 命名,以便从组件的其他位置定向更新:

blade
@island(name: 'revenue')
    <div>收入: {{ $this->revenue }}</div>
@endisland

<button type="button" wire:click="$refresh" wire:island="revenue">
    刷新收入
</button>

wire:island 指令将更新限定到特定的 islands。

为什么使用 Islands?

Islands 提供了性能隔离,无需创建单独的子组件、管理 props 或处理组件通信的开销。

适用场景:

  • 需要隔离昂贵的计算
  • 需要在单个组件内实现独立更新区域
  • 希望比嵌套组件更简单的架构

了解更多关于 islands →

参考

blade
@island(
    ?string $name = null,
    bool $lazy = false,
    bool $defer = false,
)
    <!-- 内容 -->
@endisland
参数类型默认值说明
$name?stringnull用于 wire:island 定向更新的唯一名称
$lazyboolfalse延迟渲染直到 island 在视口中可见
$deferboolfalse页面加载后立即加载,而非等待视口可见