[Vue] 有時候你不需要 $emit & $on

原文鏈接:https://ssshooter.com/2019-10-16-dont-need-emit-on/

在此之前,子組件到父組件的傳遞事件我一般還是使用 $emit$on,因爲這個操作理解起來並不難,代碼一般也挺清晰。

不過今天遇到這麼個情況 ——

<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 組件會顯示。本來想着在那裏操作就在哪裏取消,但是寫完了,產品大人一看,表示不行,按鈕不能在上面,應該統一放在評論內容和輸入框的下方,不妥協。

心想又要加 $emit$on 雖然麻煩,但不是難事,不過 CommentInput 本來還會複用到其他地方,只有這裏需要“取消回覆”功能,這又要做一層判斷,爲了代碼簡潔這個實現還要好好想想。結果靈感就來了 —— 使用 slot

<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 就像一個閉包,帶上了父組件的一切,棲身於子組件。

希望這個分享能給大家一點靈感

PS: 突然想起我坑了一萬年的博客評論組件現在依然還坑着……

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章