有时候会遇到点击目标区域绑定事件 / 展示效果,然后点击目标区域之外的地方就关闭效果 / 触发另一事件,为了实现这样的功能,我们需要通过比对 node 节点来进行判断,在下面我会使用 Vue3.0 的 ref 属性用法与 node.contains 方法来进行案例展示。

useClickOutside.ts 核心判断文件内容如下

// 判断元素是否在 node 区域之外
import { ref, onMounted, onUnmounted, Ref } from 'vue'

const useClickOutside = (elementRef: Ref<HTMLElement | null>) => {

  // 设置一个导出值
  const isClickOutside = ref(false);
  
  // 给界面绑定上事件
  const handler = (e: MouseEvent) => {
    if (elementRef.value) {
      // e.target 有可能是为 null 所以需要断言
      if (elementRef.value.contains(e.target as HTMLElement)) {
        // 判断目标节点是不是当前的节点
        isClickOutside.value = false;
      } else {
        isClickOutside.value = true
      }
    }
  }
  onMounted(() => {
    document.addEventListener('click', handler);
  });
  onUnmounted(() => {
    document.removeEventListener('click', handler);
  });
  return isClickOutside;
}

export default useClickOutside;

Vue 文件内容

<template>
  <div ref="dropdownRef">
    <!-- ......里面是内容...... -->
  </div>
</template>

<script lang="ts">
import { defineComponent, ref, watch } from 'vue';
import useClickOutside from './useClickOutside';
export default defineComponent({
	setup() {
	    // 名字要和 ref 的值一样!!!!
	    const dropdownRef = ref<null | HTMLElement>(null);
	    
		// 控制点击事件
		const isClickOutside = useClickOutside(dropdownRef);
		
		// 通过 watch 去监听事件的变化
		watch(isClickOutside, () => {
		   if (isClickOutside.value) {
		       // ......这里是你要操作的内容
		   }
		})
		
		// 这里要导出 ref 的值,才能和界面进行关联
		return { dropdownRef }
	}
})
</script>
Logo

前往低代码交流专区

更多推荐