You need three things for this
NOTE: Options Api gist here
1- A compontent ref like this:
<template>
<div
ref="componentRef"
class="general-style"
>
</div>
</template>
<script setup>
import { ref } from 'vue'
const componentRef = ref()
</script>
2- The next composable:
import {onBeforeUnmount, onMounted} from 'vue'
export default function useDetectOutsideClick(component, callback) {
if (!component) return
const listener = (event) => {
if (event.target !== component.value && event.composedPath().includes(component.value)) {
return
}
if (typeof callback === 'function') {
callback()
}
}
onMounted(() => { window.addEventListener('click', listener) })
onBeforeUnmount(() => {window.removeEventListener('click', listener)})
return {listener}
}
3- Use within your component and send the ref as composable param:
<template>
<div
ref="componentRef"
class="general-style"
>
</div>
</template>
<script setup>
import { ref } from 'vue'
import useDetectOutsideClick from '/useDetectOutsideClick'
const componentRef = ref()
const exampleComposableText = ref('hello')
useDetectOutsideClick(componentRef, () => {
exampleComposableText.value = 'edit hello'
})
</script>
Summary: Just declare a ref, point the ref to the template element and send it to the composable as first parameter. The second parameter of the composable is the callback what do you want to execute when clicked out.
Happy Code!
Latest comments (1)
On popup div, i placed a ref, to close it when clicked outside, and there is a button for opening a popup, upon clicking button it treats it the outside element and goes to callback function, where popup close logic is implemented and in result popup never opens, please suggest to ignore button click