Livewire中mount方法调用$this->emit()事件不触发问题咨询
问题根源
Livewire的生命周期执行顺序决定了mount()方法中抛出的事件无法被正常监听:
mount()仅在组件初始请求的服务端阶段执行,此时组件还未完成前端水合、监听器注册流程,同时组件自身还未加入Livewire的事件处理栈,$this->emit()抛出的事件找不到对应监听目标,自然不会触发。- 把
emit放到render()方法中出现多次触发的原因也和生命周期有关:render()会在服务端初始渲染、前端水合、后续每次组件更新时重复执行,没有加拦截判断的话就会多次抛出事件。
可行解决方案
根据实际场景选对应方案即可:
- 场景1:仅需要在组件初始化时执行自身的
test()方法
不需要走emit事件逻辑,直接在mount()中调用对应方法即可,性能更高也没有生命周期冲突:public function mount() { $this->test(); } - 场景2:需要在初始化时通知同页面其他Livewire组件
把emit逻辑移到booted()生命周期方法中,该方法在组件属性挂载完成、所有监听器注册完毕后、视图渲染前执行,抛出的事件可以被同请求内的其他组件正常捕获:public function booted() { $this->emit('test'); } - 场景3:需要等前端完全加载完成后再触发事件(包括触发JS监听、跨组件通信)
直接在组件对应的视图文件中,通过Livewire前端初始化钩子触发事件,完全规避服务端生命周期冲突,也不会出现重复触发问题:<!-- 对应livewire.ministries.uniform.header视图文件 --> <div> <!-- 原有组件内容 --> </div> <script> document.addEventListener('livewire:initialized', () => { @this.emit('test') }) </script>
注意:不要把事件触发逻辑放到
render()方法中,该方法触发频率高,很容易出现重复执行、逻辑异常的问题,如果非要使用必须加首次渲染标记拦截,但非必要不推荐这种写法。
内容的提问来源于stack exchange,提问作者Jesus Rojas
相关产品推荐
相关产品推荐

