Skip to content

vClickOutSide

介绍

v-click-outside 是一个 Vue 指令,用于检测点击元素外部的事件。

源码
ts
import type { App, DirectiveBinding } from 'vue';

export const vClickOutside = {
  beforeMount(el: any, binding: DirectiveBinding) {
    el.clickOutsideEvent = function (event: MouseEvent) {
      if (!(el === event.target || el.contains(event.target))) {
        binding.value(event);
      }
    };
    document.body.addEventListener('click', el.clickOutsideEvent);
  },
  unmounted(el: any) {
    document.body.removeEventListener('click', el.clickOutsideEvent);
  }
};

export const clickOutsideInstall = (app: App) => {
  app.directive('click-outside', vClickOutside);
};

使用

全局注册

ts
import { createApp } from 'vue';
import { clickOutsideInstall } from '...';  // 引入 clickOutsideInstall
import App from './App.vue';

const app = createApp(App);
clickOutsideInstall(); // 全局注册
app.mount('#app');

在组件中使用:

vue
<template>
  <div v-click-outside="onClickOutside">
    <p>点击外部区域</p>
  </div>
</template>

<script setup>
const onClickOutside = () => {
  console.log('点击外部区域')
}
</script>

局部注册

示例代码
vue
<script lang="ts" setup>
import { vClickOutside } from "@utils/directives/vClickOutside";
import { ref } from "vue";

const count = ref(0);
const onClickOutside = () => {
  count.value++;
};
</script>

<template>
  <div class="container">
    <div class="child" v-click-outside="onClickOutside">Click outside me</div>
    <div>Click outside count: {{ count }}</div>
  </div>
</template>

<style lang="scss" scoped>
.container {
  padding: 0 10px;
  height: 100px;
  border: 1px solid #999;

  .child {
    margin: 5px auto;
    height: 50px;
    width: 200px;
    background-color: #f0f0f0;
  }
}
</style>
Click outside me
Click outside count: 0

Released under the MIT License.