@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()
{
// Expensive calculation...
return Revenue::yearToDate();
}
};
?>
<div>
@island
<div>
Revenue: {{ $this->revenue }}
<button type="button" wire:click="$refresh">Refresh</button>
</div>
@endisland
<div>
<!-- Other content... -->
</div>
</div>点击「Refresh」按钮时,只有 island 会重新渲染——组件的其余部分保持不变。
懒加载 island
使用 lazy 参数可将 island 的初始渲染推迟到页面加载之后:
blade
@island(lazy: true)
<div>
Revenue: {{ $this->revenue }}
</div>
@endislandisland 最初显示加载状态,然后在单独的请求中获取其内容。
Lazy 与 Deferred
默认情况下,lazy 会等到 island 在视口中可见。使用 defer 可在页面加载后立即加载:
blade
{{-- Loads when scrolled into view --}}
@island(lazy: true)
<!-- ... -->
@endisland
{{-- Loads immediately after page load --}}
@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>
Revenue: {{ $this->revenue }}
</div>
@endisland命名 island
给 island 命名,以便从组件的其他位置定位它们:
blade
@island(name: 'revenue')
<div>Revenue: {{ $this->revenue }}</div>
@endisland
<button type="button" wire:click="$refresh" wire:island="revenue">
Refresh revenue
</button>wire:island 指令将更新限定到特定 island。
为什么使用 island?
Island 提供性能隔离,而无需创建独立子组件、管理 props 或处理组件通信的开销。
在以下情况使用 island:
- 希望隔离昂贵计算
- 需要在一个组件内拥有独立的更新区域
- 希望架构比嵌套组件更简单
参考
blade
@island(
?string $name = null,
bool $lazy = false,
bool $defer = false,
)
<!-- Content -->
@endisland| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
$name | ?string | null | 用于通过 wire:island 定位该 island 的唯一名称 |
$lazy | bool | false | 推迟渲染,直到 island 在视口中可见 |
$defer | bool | false | 页面加载后立即加载,而不等待视口可见 |