如何在两个DOM元素上使用VueUse的onClickOutside?
解决VueUse onClickOutside监听多个元素外部点击的问题
方案1:使用数组类型Ref(推荐)
Vue支持通过函数式ref将多个非循环渲染的元素存入同一个数组Ref,而VueUse的onClickOutside原生支持接收元素数组作为监听目标,会自动判断点击是否在任意目标元素内部。
代码示例:
import { ref } from 'vue' import { onClickOutside } from '@vueuse/core' // 定义数组类型的ref存储目标元素 const targetRefs = ref([]) const state = ref({ active: true }) // 监听数组内所有元素的外部点击 onClickOutside(targetRefs, () => { state.value.active = false })
对应DOM结构:
<!-- 用函数式ref将元素加入数组 --> <img ... ref="el => el && targetRefs.value.push(el)" /> <button ... ref="el => el && targetRefs.value.push(el)" />
方案2:手动判断点击范围
给两个元素分别绑定独立Ref,在onClickOutside回调中手动检查点击目标是否属于任意一个元素的范围。
代码示例:
import { ref } from 'vue' import { onClickOutside } from '@vueuse/core' const elementRef1 = ref(null) const elementRef2 = ref(null) const state = ref({ active: true }) // 监听全局点击,手动判断范围 onClickOutside(document.body, (event) => { const isInEl1 = elementRef1.value?.contains(event.target) const isInEl2 = elementRef2.value?.contains(event.target) // 仅当点击不在两个元素内时触发逻辑 if (!isInEl1 && !isInEl2) { state.value.active = false } })
对应DOM结构:
<img ... ref="elementRef1" /> <button ... ref="elementRef2" />
注意:方案2中需要处理Ref未挂载(值为null)的情况,使用可选链操作符
?.可以避免报错。
内容的提问来源于stack exchange,提问作者Artur Müller Romanov
相关产品推荐
相关产品推荐

