咨询:x-init阶段无法访问x-modelable属性的wire:model值的解决办法
问题描述
我用Alpine与Livewire结合编写了一个计数器组件:
<div> <div x-data="{ value: 0 }" x-modelable="value" wire:model.live="counter" x-init="console.log('init', value)" <!-- 初始化时value输出为0,但Livewire中$counter设为5 --> > <button x-on:click="value--" type="button" class="border border-gray-600 rounded-full h-8 w-8 flex justify-center items-center hover:bg-gray-100">-</button> <button x-on:click="value++" type="button" class="border border-gray-600 rounded-full h-8 w-8 flex justify-center items-center hover:bg-gray-100">+</button> </div> {{ $counter }} </div>
PHP代码中设置了$counter = 5,计数器功能正常:点击按钮可同步Alpine与Livewire端的增减数值,但x-init阶段console.log输出的value为初始值0,而非wire:model绑定的5。如果无法在此阶段获取wire:model的值,将无法完成如通过init函数设置markdown编辑器初始内容这类操作。
想问这是必须使用$wire.entangle的限制吗?有没有其他解决方法?
解决方法
这不是必须使用$wire.entangle的限制,有两种可行方案:
方案1:直接在x-data中注入Livewire初始值
既然PHP端已经设置了$counter = 5,可以直接将该值注入到Alpine的x-data中,让Alpine初始化时就拿到正确的数值,同时不影响后续双向同步:
<div> <div x-data="{ value: @js($counter) }" x-modelable="value" wire:model.live="counter" x-init="console.log('init', value)" > <button x-on:click="value--" type="button" class="border border-gray-600 rounded-full h-8 w-8 flex justify-center items-center hover:bg-gray-100">-</button> <button x-on:click="value++" type="button" class="border border-gray-600 rounded-full h-8 w-8 flex justify-center items-center hover:bg-gray-100">+</button> </div> {{ $counter }} </div>
这种方式最简单,组件渲染时就把Livewire的初始值传递给Alpine,x-init执行时自然能获取到正确的数值。
方案2:利用Livewire的wire:init指令
Livewire的wire:init会在组件完成初始化、数据同步到前端后执行,结合$nextTick确保数据同步完成后再执行初始化逻辑:
<div> <div x-data="{ value: 0 }" x-modelable="value" wire:model.live="counter" wire:init=" $nextTick(() => { $refs.alpineComp.__x.$data.value = @js($counter); console.log('init', $refs.alpineComp.__x.$data.value); }) " x-ref="alpineComp" > <button x-on:click="value--" type="button" class="border border-gray-600 rounded-full h-8 w-8 flex justify-center items-center hover:bg-gray-100">-</button> <button x-on:click="value++" type="button" class="border border-gray-600 rounded-full h-8 w-8 flex justify-center items-center hover:bg-gray-100">+</button> </div> {{ $counter }} </div>
问题根源
Alpine的x-init是在DOM渲染完成后立刻执行的,而Livewire的wire:model数据同步是组件初始化的后续步骤,执行时机晚于x-init,所以初始阶段x-init只能拿到Alpine自身的默认值0。
内容的提问来源于stack exchange,提问作者Adam Lambert
相关产品推荐
相关产品推荐

