Skip to content

封装 useEventListener 函数

更新: 2025/3/13 12:08:48 字数: 0 字

需求分析

  我们在开发中,会遇到很多场景,需要监听 DOM 元素的事件,比如:

  • 监听滚动事件
  • 监听点击事件
  • 监听键盘事件
  • ....
vue

<script setup>
/*使用监听事件*/
import {onMounted, onUnmounted} from "./vue";

const handleScroll = () => {
    console.log('滚动事件')
}

onMounted(() => {
    window.addEventListener('scroll', handleScroll)
})

onUnmounted(() => {
    window.removeEventListener('scroll', handleScroll)
})

</script>
  • 封装一个 useEventListener 函数,可以监听 DOM 元素的事件,并返回一个函数,用于取消监听。

封装思路

  封装 useEventListener 函数,需要传入三个参数:

  • target:监听的目标元素,可以是一个 DOM 元素,也可以是一个 Ref 对象。
  • event:监听的事件类型,如:scroll、click、keydown 等。
  • callback:监听的事件回调函数。
vue

<script setup>
  import {useEventListener} from "@vueuse/core";


  const handleScroll = () => {
    console.log('滚动事件')
  }

  const off = useEventListener('scroll', handleScroll)
  /*或者*/
  const el = ref()
  useEventListener(el, 'scroll', handleScroll)
</script>

下面的是代码实现

ts
import {unref} from "@vue/reactivity";
import {onUnmounted} from "@vue/runtime-core";

export function useEventListener(...args) {
    // 判断第一个参数是否为 字符串,如果是 element 就是 windows 对象,否则是 Ref 对象
    const element = isString(args[0]) ? window : args.shift()

    let off = () => {
    }

    const stop = watch(() => unref(element),
        (el) => {
            off() // 关闭上一次注册的事件
            // 如果 el 不存在,则返回
            if (!el) return
            off = () => el.removeEventListener(...args)
        },
        {
            // 第一次就执行
            immediate: true
        }
    )

    // 当 scope 销毁时,执行 off()
    onScopeUnmount(() => {
        off()
    })

    // 这个是组件的生命周期函数,当组件销毁时,执行 off()
    // onUnmounted()


    return () => {
        off()
        stop()
    }
}

道友再会.