diff --git a/src/directives/clickOutSide/index.ts b/src/directives/clickOutSide/index.ts new file mode 100644 index 0000000..fc5b4bc --- /dev/null +++ b/src/directives/clickOutSide/index.ts @@ -0,0 +1,41 @@ +// 自定义指令点击非自身事件(空白处) +export const clickOutSide = { + beforeMount(el: any, binding: any) { + function documentHandler(e: any) { + console.log(el); //绑定v-click-outside的元素 + console.log(e.target); //点击的元素 + console.log(binding); //绑定指令的对象 + + // 判断点击的元素是否是自身或者内部元素(因为点自己,或者自己内部的元素,是不能关闭弹窗的,只有点击页面其他空白处才能关闭) + if (el.contains(e.target) || el === e.target) { + return false; + } + + // 判断点击的元素是否是排除的元素,因为不排除点击的元素,也会触发binding.value.handler => hideDropdown(即关闭弹窗,这就导致弹窗永远一打开就被关闭了) + console.log(binding.value.exclude === e.target); + if (binding.value.exclude && binding.value.exclude === e.target) { + return false; + } + /** + * 总结有两种情况不做任何操作 + * 1. 点击的元素是自身或者内部元素 + * 2. 点击的元素是排除的元素(即点击元素自身) + */ + + // 判断指令中是否绑定了函数 + console.log('判断指令中是否绑定了函数', binding); + if (binding.value.handler) { + console.log('有绑定函数,执行函数'); + // 有绑定函数,则执行函数 + binding.value.handler(e); + } + } + // 给当前元素绑定个私有变量,方便在unmounted中可以解除事件监听 + el.__vueClickOutside__ = documentHandler; + document.addEventListener('click', documentHandler); + }, + unmounted(el: any) { + document.removeEventListener('click', el.__vueClickOutside__); + delete el.__vueClickOutside__; + }, +}; diff --git a/src/directives/index.ts b/src/directives/index.ts index d01fe71..c413532 100644 --- a/src/directives/index.ts +++ b/src/directives/index.ts @@ -1,6 +1,8 @@ -export * from "./auth"; -export * from "./copy"; -export * from "./longpress"; -export * from "./optimize"; -export * from "./perms"; -export * from "./ripple"; +export * from './auth'; +export * from './copy'; +export * from './longpress'; +export * from './optimize'; +export * from './perms'; +export * from './ripple'; + +export * from './clickOutSide'; diff --git a/src/router/modules/demo.ts b/src/router/modules/demo.ts index 6174732..09e2769 100644 --- a/src/router/modules/demo.ts +++ b/src/router/modules/demo.ts @@ -13,6 +13,10 @@ const titleArr = [ key: 'importOrExportExcel', title: '导入导出excel', }, + { + key: 'clickOutSide', + title: '点击空白处关闭弹窗或者下拉菜单', + }, ]; // @/views/demo/**/*.vue diff --git a/src/views/demo/clickOutSide/index.vue b/src/views/demo/clickOutSide/index.vue new file mode 100644 index 0000000..dc5f057 --- /dev/null +++ b/src/views/demo/clickOutSide/index.vue @@ -0,0 +1,48 @@ + + + + + diff --git a/src/views/demo/tools/components/cmp.vue b/src/views/demo/tools/components/cmp.vue index db131ca..4512729 100644 --- a/src/views/demo/tools/components/cmp.vue +++ b/src/views/demo/tools/components/cmp.vue @@ -1,15 +1,9 @@