原文連接:https://ssshooter.com/2019-10-16-dont-need-emit-on/html
在此以前,子組件到父組件的傳遞事件我通常仍是使用 $emit
和 $on
,由於這個操做理解起來並不難,代碼通常也挺清晰。閉包
不過今天遇到這麼個狀況 ——ssh
<div class="button-group"> <button @click="item.reply = !item.reply"> {{item.reply?'取消回覆':'回覆'}} </button> <button @click="item.editing = !item.editing"> {{item.editing?'取消修改':'修改'}} </button> <button @click="removeComment(item.id)">刪除</button> </div> <CommentInput v-if="item.reply" @submit="item.reply = false" :lxid="lxid" :parentId="item.id" />
這是一個評論組件的一部分,button-group
是回覆、修改、刪除 3 個按鈕,點擊回覆的話下面的 CommentInput
組件會顯示。原本想着在那裏操做就在哪裏取消,可是寫完了,產品大人一看,表示不行,按鈕不能在上面,應該統一放在評論內容和輸入框的下方,不妥協。code
心想又要加 $emit
和 $on
雖然麻煩,但不是難事,不過 CommentInput
原本還會複用到其餘地方,只有這裏須要「取消回覆」功能,這又要作一層判斷,爲了代碼簡潔這個實現還要好好想一想。結果靈感就來了 —— 使用 slot
。htm
<div class="button-group"> <button @click="replyToggle(item)">回覆</button> <button v-if="loginInfo.operatorname === item.authorName" @click="editToggle(item)" > {{item.editing?'取消修改':'修改'}} </button> <button v-if="loginInfo.operatorname === item.authorName" @click="removeComment(item.id)" > 刪除 </button> </div> <CommentInput v-if="item.reply" @submit="item.reply = false" :lxid="lxid" :parentId="parentId||item.id" > <div class="button-group"> <button @click="replyToggle(item)">取消回覆</button> </div> </CommentInput>
slot
自己仍是很經常使用的,只是第一次主動意識到使用 slot
能夠顯著解決事件傳遞問題。直接把取消回覆按鈕用 slot
嵌入 CommentInput
,直接使用父組件的 replyToggle
方法,免去從新寫 $emit
和 $on
的麻煩,順便還解決了其餘地方不須要「取消回覆」的問題,十分有效!事件
其實感受 slot 就像一個閉包,帶上了父組件的一切,棲身於子組件。rem
但願這個分享能給你們一點靈感get
PS: 忽然想起我坑了一萬年的博客評論組件如今依然還坑着……博客