Livewire自定义DatePicker点击选日期时wire:model不更新值
问题根因

wire:model 默认依赖监听输入框的原生input、change事件完成值同步。你当前使用的客户端日期选择器(配置了datepicker datepicker-autohide属性)选中日期时,是通过JavaScript直接修改input节点的value属性,不会主动触发上述原生事件,因此Livewire无法感知到值变更,只有手动键盘输入触发原生事件时,绑定值才会更新。
另外你的组件代码存在一个小瑕疵:input标签上重复写了两次id="{{ $wireModel }}"属性,建议删除其中一个,避免DOM结构异常。
修复方案
方案1:选值后手动触发原生事件(改动最小)
在日期选择器组件末尾添加一段JS,监听日期选择完成事件,主动派发原生input事件通知Livewire值已变更:
<!-- 追加到日期选择器组件代码末尾 --> <script> document.addEventListener('DOMContentLoaded', () => { const input = document.getElementById('{{ $wireModel }}'); // 适配Flowbite等主流datepicker的选值事件,如果你用的库事件名不同替换为对应名称即可 input.addEventListener('changeDate', () => { input.dispatchEvent(new Event('input', { bubbles: true })); }) }) </script>
这段代码不需要改动原有业务逻辑,只需要加一段事件触发逻辑即可生效。
方案2:用Alpine做绑定桥接(适配性更好)
如果不想维护额外的事件监听代码,可以借助Livewire自带的@entangle指令,通过AlpineJS做双向绑定桥接,彻底解决JS改值无法同步的问题:
<!-- 外层容器加x-data做状态共享 --> <div x-data="{ pickerValue: @entangle($wireModel) }" class="relative"> <div class="absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none"> <svg class="w-5 h-5 text-gray-500 dark:text-gray-400" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M6 2a1 1 0 00-1 1v1H4a2 2 0 00-2 2v10a2 2 0 002 2h12a2 2 0 002-2V6a2 2 0 00-2-2h-1V3a1 1 0 10-2 0v1H7V3a1 1 0 00-1-1zm0 5a1 1 0 000 2h8a1 1 0 100-2H6z" clip-rule="evenodd"></path></svg> </div> <!-- 原有input的wire:model替换为x-model绑定共享变量 --> <input id="{{ $wireModel }}" class="block rounded-t-lg pl-10 px-2.5 pb-2.5 pt-5 w-full text-sm text-gray-900 bg-gray-50 dark:bg-gray-700 border-0 border-b-2 border-gray-300 appearance-none dark:text-white dark:border-gray-600 dark:focus:border-blue-500 focus:outline-none focus:ring-0 focus:border-blue-600 peer @error($wireModel) dark:border-red-500 focus:outline-none focus:ring-0 border-red-600 focus:border-red-600 dark:focus-border-red-500 @enderror" datepicker datepicker-autohide type="text" placeholder=" " name="{{ $wireModel }}" x-model="pickerValue" /> <label for="{{ $wireModel }}" class="absolute text-sm text-gray-500 dark:text-gray-400 duration-300 transform -translate-y-4 scale-75 top-4 z-10 origin-[0] left-2.5 peer-focus:text-blue-600 peer-focus:dark:text-blue-500 peer-placeholder-shown:scale-100 peer-placeholder-shown:translate-y-0 peer-focus:scale-75 peer-focus:-translate-y-4 @error($wireModel) e-75 top-4 z-10 origin-[0] left-2.5 text-red-600 dark:text-red-500 @enderror " style="left: 2.625rem;">{{ $label }}</label> </div> @error($wireModel) <p class="mt-2 text-xs text-red-600 dark:text-red-400">{{ $message }}</p> @enderror
@entangle会让Alpine的变量和Livewire的绑定值实时同步,Alpine的x-model可以正确识别JS对input值的修改,不需要额外写事件监听逻辑,长期维护更稳定。
内容的提问来源于stack exchange,提问作者Pusoy
相关产品推荐
相关产品推荐

