封装 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()
}
}