Vue自動移除事件監聽


在vue中實現一個hook,在mounted添加事件監聽,頁面銷毀時移除。

默認函數有四個參數[target, type, listener, options]

target是EventTarget,作為注冊監聽器的容器,默認是window

后三個參數是addEventListener的參數

export function useEventListener(...args) {
  let target, type, listener, options
  if (isString(args[0])) {
    [type, listener, options] = args
    target = window
  } else {
    [target, type, listener, options] = args
  }
}

首先判斷第一個實參是否為字符串,來決定target的值

然后定義一個clean變量賦值為空函數() => {}

然后需要使用watch,用之前我們需要知道watch方法返回的一個unwatch方法。

  const stopWatch = watch(
    () => unref(target),
    (el) => {
      console.log('監聽觸發');
      cleanup()
      if (!el) return
      el.addEventListener(type, listener, options)
      cleanup = () => {
        el.removeEventListener(type, listener, options)
        cleanup = noop
      }
    },
    { immediate: true, flush: 'post' }
  )

給偵聽源加上unref方法,這樣可以給ref的虛擬dom添加監聽。

設置immediate為true,來立即執行。

import { watch, unref, onScopeDispose } from 'vue'
export function useEventListener(...args) {
  let target, type, listener, options
  if (isString(args[0])) {
    [type, listener, options] = args
    target = window
  } else {
    [target, type, listener, options] = args
  }
  
  if (!target) return noop
  
  let cleanup = noop

  const stopWatch = watch(
    () => unref(target),
    (el) => {
      console.log('監聽觸發');
      cleanup()
      if (!el) return
      el.addEventListener(type, listener, options)
      cleanup = () => {
        el.removeEventListener(type, listener, options)
        cleanup = noop
      }
    },
    { immediate: true, flush: 'post' }
  )

  const stop = () => {
    stopWatch()
    cleanup()
  }

  onScopeDispose(stop)

  return stop
}

function isString(str) {
  return typeof str === 'string'
}
const noop = () => {}

onScopeDispose

在當前活躍的 effect 作用域上注冊一個處理回調。該回調會在相關的 effect 作用域結束之后被調用。

該方法在復用組合式函數時可用作 onUmounted 的非組件耦合替代品,因為每個 Vue 組件的 setup() 函數也同樣在 effect 作用域內被調用。


免責聲明!

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



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