Livewire Development 是一个面向 Livewire 4 组件开发的技能,用于在创建、更新或修改 Livewire 组件时提供指导。
适用时机
在以下情况激活该技能:创建或修改 Livewire 组件;使用 wire: 指令(model、click、loading、sort、intersect);实现 islands 或异步操作;编写 Livewire 组件测试。
文档
使用 search-docs 获取详细的 Livewire 4 模式与文档。
基本用法
创建组件:
- 单文件组件(v4 默认):php artisan make:livewire create-post
- 多文件组件:php artisan make:livewire create-post --mfc
- 类式组件(v3 风格):php artisan make:livewire create-post --class
- 带命名空间:php artisan make:livewire Posts/CreatePost
在格式之间转换:使用 php artisan livewire:convert create-post 在单文件、多文件和类式格式之间转换。
组件格式参考:
- 单文件(SFC):默认,PHP + Blade 在一个文件中
- 多文件(MFC):--mfc,分离的 PHP 类、Blade、JS、测试
- 类式:--class,传统 v3 风格类
- 视图式:⚡ 前缀,仅 Blade 加函数式状态
Livewire 4 特性
相对 Livewire 3 的关键变化(这些在 Livewire 4 中已改变,但应用可能尚未更新,需验证应用设置以遵循现有约定):
- 使用 Route::livewire() 处理整页组件;配置键重命名:layout → component_layout,lazy_placeholder → component_placeholder。
- wire:model 现在默认忽略子事件(使用 wire:model.deep 恢复旧行为);wire:scroll 重命名为 wire:navigate:scroll。
- 组件标签必须正确闭合;wire:transition 现在使用 View Transitions API(修饰符已移除)。
- JavaScript:$wire.$js('name', fn) → $wire.$js.name = fn;commit/request 钩子 → interceptMessage()/interceptRequest()。
新特性:
- 组件格式:单文件(SFC)、多文件(MFC)、视图式组件。
- Islands(@island)用于隔离更新;异步操作(wire:click.async、#[Async])用于并行执行。
- 延迟/打包加载:defer、lazy.bundle 用于优化组件加载。
特性用法与用途:
- Islands:@island(name: 'stats'),隔离更新区域
- Async:wire:click.async 或 #[Async],非阻塞操作
- Deferred:defer 属性,页面渲染后加载
- Bundled:lazy.bundle,多个一起加载
新指令: wire:sort、wire:intersect、wire:ref、.renderless、.preserve-scroll 可用。触发网络请求的元素会自动添加 data-loading 属性。
- wire:sort:拖放排序
- wire:intersect:视口交叉检测
- wire:ref:供 JS 使用的元素引用
- .renderless:不渲染的组件
- .preserve-scroll:保留滚动位置
最佳实践:
- 循环中始终使用 wire:key
- 使用 wire:loading 显示加载状态
- 使用 wire:model.live 实现即时更新(默认是防抖的)
- 在操作中验证和授权(像 HTTP 请求一样对待)
配置: smart_wire_keys 默认为 true;新配置项:component_locations、component_namespaces、make_command、csp_safe。
Alpine 与 JavaScript: wire:transition 使用浏览器 View Transitions API;$errors 和 $intercept 魔术属性可用。非阻塞 wire:poll 和并行 wire:model.live 更新提升性能。拦截器与钩子参见 reference/javascript-hooks.md。
测试: Livewire::test(Counter::class) ->assertSet('count', 0) ->call('increment') ->assertSet('count', 1);
验证:
- 浏览器控制台:检查 JS 错误
- 网络标签:验证 Livewire 请求返回 200
- 确保所有 @foreach 循环上有 wire:key
常见陷阱:
- 循环中缺少 wire:key → 意外的重新渲染
- 期望 wire:model 实时更新 → 使用 wire:model.live
- 未闭合的组件标签 → v4 中的语法错误
- 使用已弃用的配置键或 JS 钩子
- 单独引入 Alpine.js(Livewire 4 已内置)