Livewire组件触发事件后消失问题求助(附代码)
Livewire聊天应用触发事件后chat-list组件消失问题
我用Livewire开发了一款聊天应用,原本希望触发事件时向其他组件转发事件,但触发chatUserSelected事件后,chat-list组件直接从视图中消失了,找不到原因。
触发事件的视图代码
<div class="flex flex-row py-2 px-2 items-center border-b-2 cursor-pointer hover:bg-gray-100" wire:click="$emit('chatUserSelected',{{$conversation}})">
chat-list组件的PHP代码
protected $listeners = ['chatUserSelected']; public $conversations; public $selectedConversation; public function chatUserSelected(Conversation $conversation) { $this->selectedConversation = $conversation; $receiverInstance = KontakModel::find($conversation->kontak_id); $this->emitTo('chat.chat-box','loadConversation',$this->selectedConversation,$receiverInstance); $this->emitTo('chat.send-message','updateSendMessage',$this->selectedConversation,$receiverInstance); } public function mount() { $this->auth_id = auth()->id(); $this->conversations = Conversation::orderBy('last_time_message','DESC')->where('solved_at',NULL)->get(); // dd($this->conversations); } public function render() { return view('livewire.chat.chat-list', ); }
视图变化情况
- 触发事件前:左侧显示完整的chat-list会话列表,包含用户头像、会话名称、最新消息、未读计数和时间戳
- 触发事件后:左侧的chat-list组件完全消失,页面仅显示侧边栏和聊天框区域
主视图代码
<div class="flex flex-row justify-between bg-white h-screen" x-data="chatApp"> @livewire('chat.chat-list') @livewire('admin.side-bar') <!-- message --> @livewire('chat.chat-box') <!-- end message --> </div>
chat.chat-list.blade.php代码
<div class="overflow-y-auto"> @forelse ($conversations as $conversation) <div class="flex flex-row py-2 px-2 items-center border-b-2 cursor-pointer hover:bg-gray-100" wire:key="{{$conversation->id}}" wire:click="$emit('chatUserSelected',{{$conversation}})"> <div class="w-1/4"> <img src="https://source.unsplash.com/otT2199XwI8/600x600" class="object-cover h-12 w-12 rounded-full" alt="" /> </div> <div class="w-full"> <div class="text-lg font-semibold">{{ $conversation->kontak->name }}</div> <span class="text-gray-500">{{$conversation->messages->sortBy('created_at')->last()->body}}</span> </div> <div class="w-2/12"> @php $unread = $conversation->messages->where('status', NULL)->where('category','receive')->count() @endphp @if ($unread > 0) <div class="text-sm text-center font-light rounded-full bg-red-600 text-white min-w-5 h-5">{{$unread}}</div> @endif <span class="text-xs">{{$conversation->messages->sortBy('created_at')->last()->created_at->shortAbsoluteDiffForHumans()}}</span> </div> </div> @empty <div class="flex flex-row py-2 px-2 items-center border-b-2 text-2xl text-center"> <div class="text-center m-auto"> No Conversation </div> </div> @endforelse </div>
问题原因及解决方法
- 事件参数传递错误:直接在
wire:click中传递Eloquent模型会生成无效的JavaScript代码(模型会被转成字符串而非可序列化数据),触发事件时引发Livewire组件报错,导致组件渲染失败消失。 - 核心修复步骤:
- 传递模型ID而非整个模型,修改触发事件的代码:
wire:click="$emit('chatUserSelected', {{ $conversation->id }})" - 修改
chatUserSelected方法,通过ID重新获取模型实例:public function chatUserSelected($conversationId) { $this->selectedConversation = Conversation::findOrFail($conversationId); $receiverInstance = KontakModel::find($this->selectedConversation->kontak_id); $this->emitTo('chat.chat-box','loadConversation',$this->selectedConversation,$receiverInstance); $this->emitTo('chat.send-message','updateSendMessage',$this->selectedConversation,$receiverInstance); }
- 传递模型ID而非整个模型,修改触发事件的代码:
- 额外优化:在
render方法中重新查询会话数据,确保组件更新后数据不丢失:public function render() { $this->conversations = Conversation::orderBy('last_time_message','DESC')->where('solved_at',NULL)->get(); return view('livewire.chat.chat-list'); }
内容的提问来源于stack exchange,提问作者Blue Moon
相关产品推荐
相关产品推荐

