onClickOutside
监听元素外的点击事件。适用于模态框或下拉菜单等场景。
示例
用法
vue
<script setup>
import { onClickOutside } from '@vueuse/core'
import { useTemplateRef } from 'vue'
const target = useTemplateRef<HTMLElement>('target')
onClickOutside(target, event => console.log(event))
</script>
<template>
<div ref="target">
Hello world
</div>
<div>外部元素</div>
</template>
如果您需要更好地控制触发处理程序,可以使用 controls
选项。
ts
const { cancel, trigger } = onClickOutside(
modalRef,
(event) => {
modal.value = false
},
{ controls: true },
)
useEventListener('pointermove', (e) => {
cancel()
// or
trigger(e)
})
组件用法
vue
<template>
<OnClickOutside :options="{ ignore: [/* ... */] }" @trigger="count++">
<div>
点击我外面
</div>
</OnClickOutside>
</template>
指令用法
vue
<script setup lang="ts">
import { vOnClickOutside } from '@vueuse/components'
import { shallowRef } from 'vue'
const modal = shallowRef(false)
function closeModal() {
modal.value = false
}
</script>
<template>
<button @click="modal = true">
打开模态框
</button>
<div v-if="modal" v-on-click-outside="closeModal">
Hello World
</div>
</template>
你还可以将处理程序设置为数组,以设置指令的配置项。
vue
<script setup>
import { vOnClickOutside } from '@vueuse/components'
import { shallowRef, useTemplateRef } from 'vue'
const modal = shallowRef(false)
const ignoreElRef = useTemplateRef<HTMLElement>('ignoreEl')
const onClickOutsideHandler = [
(ev) => {
console.log(ev)
modal.value = false
},
{ ignore: [ignoreElRef] },
]
</script>
<template>
<button @click="modal = true">
打开模态框
</button>
<div ref="ignoreElRef">
点击外部忽略元素
</div>
<div v-if="modal" v-on-click-outside="onClickOutsideHandler">
Hello World
</div>
</template>
类型声明
显示类型声明
typescript
export interface OnClickOutsideOptions<Controls extends boolean = false>
extends ConfigurableWindow {
/**
* 不应触发事件的元素列表。
*/
ignore?: MaybeRefOrGetter<(MaybeElementRef | string)[]>
/**
* 对内部事件侦听器使用捕获阶段。
* @default true
*/
capture?: boolean
/**
* 如果焦点移动到iframe,运行处理函数。
* @default false
*/
detectIframe?: boolean
/**
* Use controls to cancel/trigger listener.
* @default false
*/
controls?: Controls
}
export type OnClickOutsideHandler<
T extends {
detectIframe: OnClickOutsideOptions["detectIframe"]
controls: boolean
} = {
detectIframe: false
controls: false
},
> = (
event: T["controls"] extends true
?
| Event
| (T["detectIframe"] extends true
? PointerEvent | FocusEvent
: PointerEvent)
: T["detectIframe"] extends true
? PointerEvent | FocusEvent
: PointerEvent,
) => void
/**
* 监听元素外部的点击事件。
*
* @see https://vueuse.org/onClickOutside
* @param target 目标元素
* @param handler 事件处理器
* @param options 配置选项
*/
export declare function onClickOutside(
target: MaybeElementRef,
handler: OnClickOutsideHandler<{
detectIframe: OnClickOutsideOptions["detectIframe"]
controls: true
}>,
options: OnClickOutsideOptions<true>,
): {
stop: Fn
cancel: Fn
trigger: (event: Event) => void
}
export declare function onClickOutside(
target: MaybeElementRef,
handler: OnClickOutsideHandler<{
detectIframe: OnClickOutsideOptions["detectIframe"]
controls: false
}>,
options?: OnClickOutsideOptions<false>,
): Fn
源码
贡献者
更新日志
v12.8.0
on 3/5/2025v12.6.0
on 2/14/2025v12.5.0
on 1/22/2025v12.4.0
on 1/10/2025v12.3.0
on 1/2/202559f75
- feat(toValue): deprecate toValue
from @vueuse/shared
in favor of Vue's nativev12.0.0-beta.1
on 11/21/2024v11.3.0
on 11/21/2024v11.1.0
on 9/16/2024v10.6.0
on 11/9/2023v10.3.0
on 7/30/2023v10.2.0
on 6/16/2023