關於 Vue 自定義按鈕組件 $emit(‘click‘) 一次觸發兩次的問題


在寫自定義組件以及引用時,遇到了一個問題,也就是子組件中明明只做了一次 click 的 $emit 操作,卻在父組件中觸發了兩次事件函數。

之后,在網上找了很多方案。
有提及通過 .stop 阻止事件冒泡的方案,但通過多次測試,並沒有實質效果。
也有一個是通過 .once 的方案,但是很顯然,這個方案並不符合需求。這個方案會使得按鈕組件變成一次性觸發,不可重復操作。
之后,又找到了一個“曲線救國”的方案,也就是通過 setTimeout 的方式,讓同一個事件函數在一定時間內只能被觸發一次,避免二次觸發。雖然,這個方案,確實解決了問題,但卻在復用性上存在極大的問題,尤其是修改原有引用的源碼時,需要沒處都添加上 setTimeout。所以,這也是不太合理的。

隨后,想到了這個問題的根本原因,並不是 $emit 本身的問題,或者說,兩次觸發 handleClick 函數的,其實是兩個地方,而不是都源自於子組件的 $emit 行為。

實際上,第一次觸發 handleClick 函數的,確系子組件通過 $emit 提交的 click 事件。而另外的一次觸發,則是父組件中,作為一個自定義標簽元素的 <yt-button> 本身。

所以,要避免一次點擊,兩次觸發 handleClick 函數,最簡單的方式,就是在子組件中,把 $emit('click') 的行為去除掉。因為 click 事件,事實上在父級處就已經做了處理,並不需要在子組件中做新的處理。

目前我測試發現:

1、在el-tree類型的子組件使用$emit(‘click‘)傳送事件給父組件時,如果雙方監聽的事件名為node-click時,就會出現觸發兩次的現象,

  methods: {
    handleNodeClick(data, node, el) {
      this.selectNode = node
      // console.log(this.selectNodeId, this.idName, node)
      this.$emit('node-click', data, node, el)
      // console.log('DydFile this.$emit...')
    }
  }
<el-container style="height: calc( 100% - 42px )">
      <el-aside style="padding: 20px 20px 0;border-right: 2px solid #EDF2F7;">
        <dyd-file width="260px" @node-click="selectLeftTree" />
      </el-aside>
      <el-container>

 

2、解決辦法

1)雙方的事件傳遞監聽方法使用其他名稱,不使用node-click就能實現只觸發一次;

2)或者使用此node-click名稱,在子組件中不使用this.$emit('node-click', data, node, el),也可實現只觸發一次

 

  methods: {
    handleNodeClick(data, node, el) {
      this.selectNode = node
      // console.log(this.selectNodeId, this.idName, node)
      // this.$emit('node-click', data, node, el)
      // console.log('DydFile this.$emit...')
    }
  }

 

在子組件中注銷 this.$emit('node-click', data, node, el),父組件仍然監聽次事件名。

 

 

 

 

 node-click 為回調事件,父組件直接監聽

 

 

 

node-click


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM