Livewire多步骤表单单选框值被覆盖问题(附可测试Demo)
Livewire多步骤表单中步骤2单选框覆盖步骤1值的问题
问题描述
开发基于Livewire的迷你多步骤表单时,发现切换到步骤2并选择单选框值后,步骤1已选择的单选框值会被意外覆盖。
组件代码
<?php // app/Livewire/Counter.php namespace App\Livewire; use Livewire\Component; class Counter extends Component { public $count = 1; public $one; public $two; public function increment() { $this->count++; } public function decrement() { $this->count--; } public function render() { return view('livewire.counter'); } }
视图代码
<div> <div class="p-10"> <button wire:click="decrement" class="bg-green-500 p-4">-</button> <button wire:click="increment" class="bg-green-500 p-4">+</button> <h1>Count: {{ $count }}</h1> <br> @if ($count == 1) <input type="radio" name="page1" wire:model.live="one" value="1"> <input type="radio" name="page1" wire:model.live="one" value="2"> <input type="radio" name="page1" wire:model.live="one" value="3"> @elseif($count == 2) <input type="radio" name="page2" wire:model.live="two" value="1"> <input type="radio" name="page2" wire:model.live="two" value="2"> <input type="radio" name="page2" wire:model.live="two" value="3"> @endif <br> <p>Page one: {{ $one }}</p> <p>Page two: {{ $two }}</p> </div> </div>
布局代码
<!DOCTYPE html> <html lang="{{ str_replace('_', '-', app()->getLocale()) }}"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Laravel</title> <!-- Scripts --> @vite(['resources/css/app.css', 'resources/js/app.js']) </head> <body class="font-sans antialiased"> <livewire:counter /> </body> </html>
环境信息
- Livewire版本:v3.5.9
- Laravel版本:v11.26.0
- PHP版本:8.2
复现步骤
- 按照上述代码创建Livewire组件、视图及布局文件;
- 在步骤1中选择任意单选框值,确认页面已正确显示该值;
- 点击“+”按钮切换到步骤2;
- 在步骤2中选择任意单选框值,观察步骤1的值变化。
期望结果
步骤1和步骤2的单选框值独立存储,互不干扰,选择步骤2的值不会影响步骤1已选的值。
实际结果
选择步骤2的单选框值后,步骤1的单选框值会被覆盖为步骤2所选的值。
解决方案
原因分析
Livewire通过DOM diffing更新页面,动态切换表单元素时,若没有唯一标识,Livewire会误判元素身份,导致wire:model绑定的模型值被错误覆盖。加上wire:model.live实时绑定的特性,会加剧这种状态冲突。
修复方法
为每个步骤的表单容器添加唯一的wire:key,让Livewire准确区分不同步骤的元素:
@if ($count == 1) <div wire:key="step-1"> <input type="radio" name="page1" wire:model.live="one" value="1"> <input type="radio" name="page1" wire:model.live="one" value="2"> <input type="radio" name="page1" wire:model.live="one" value="3"> </div> @elseif($count == 2) <div wire:key="step-2"> <input type="radio" name="page2" wire:model.live="two" value="1"> <input type="radio" name="page2" wire:model.live="two" value="2"> <input type="radio" name="page2" wire:model.live="two" value="3"> </div> @endif
添加wire:key后,Livewire能正确识别每个步骤的DOM元素,确保各自的模型绑定独立,不会出现值被覆盖的问题。
内容的提问来源于stack exchange,提问作者Akif
相关产品推荐
相关产品推荐

