From 195f3ffea18bc8e9ef9f127c58b6de40a0162ae0 Mon Sep 17 00:00:00 2001 From: chenjiahan Date: Sat, 12 Sep 2020 21:29:08 +0800 Subject: [PATCH] feat(use): add useClickAway --- packages/vant-use/src/index.ts | 1 + packages/vant-use/src/useClickAway/index.ts | 27 ++++++++++ .../vant-use/src/useEventListener/index.ts | 4 +- src/composition/use-click-outside.ts | 21 -------- src/composition/use-global-event.ts | 50 ------------------- src/dropdown-menu/index.js | 10 ++-- src/number-keyboard/index.js | 8 +-- src/swipe-cell/index.js | 8 +-- 8 files changed, 37 insertions(+), 92 deletions(-) create mode 100644 packages/vant-use/src/useClickAway/index.ts delete mode 100644 src/composition/use-click-outside.ts delete mode 100644 src/composition/use-global-event.ts diff --git a/packages/vant-use/src/index.ts b/packages/vant-use/src/index.ts index 50c6f6900..f562c40c5 100644 --- a/packages/vant-use/src/index.ts +++ b/packages/vant-use/src/index.ts @@ -1,2 +1,3 @@ export { useToggle } from './useToggle'; +export { useClickAway } from './useClickAway'; export { useEventListener } from './useEventListener'; diff --git a/packages/vant-use/src/useClickAway/index.ts b/packages/vant-use/src/useClickAway/index.ts new file mode 100644 index 000000000..941fe8f7d --- /dev/null +++ b/packages/vant-use/src/useClickAway/index.ts @@ -0,0 +1,27 @@ +import { Ref, unref } from 'vue'; +import { inBrowser, useEventListener } from '../useEventListener'; + +export type UseClickAwayOptions = { + eventName?: string; +}; + +export function useClickAway( + target: Element | Ref, + listener: EventListener, + options: UseClickAwayOptions = {} +) { + if (!inBrowser) { + return; + } + + const { eventName = 'click' } = options; + + const onClick = (event: Event) => { + const element = unref(target); + if (!element.contains(event.target as Node)) { + listener(event); + } + }; + + useEventListener(eventName, onClick, { target: document }); +} diff --git a/packages/vant-use/src/useEventListener/index.ts b/packages/vant-use/src/useEventListener/index.ts index 2cad8dbe2..5903c7108 100644 --- a/packages/vant-use/src/useEventListener/index.ts +++ b/packages/vant-use/src/useEventListener/index.ts @@ -7,7 +7,7 @@ import { onDeactivated, } from 'vue'; -const inBrowser = typeof window !== 'undefined'; +export const inBrowser = typeof window !== 'undefined'; let supportsPassive = false; if (inBrowser) { @@ -32,7 +32,7 @@ export type UseEventListenerOptions = { export function useEventListener( type: string, listener: EventListener, - options: UseEventListenerOptions + options: UseEventListenerOptions = {} ) { if (!inBrowser) { return; diff --git a/src/composition/use-click-outside.ts b/src/composition/use-click-outside.ts deleted file mode 100644 index db64eb2a0..000000000 --- a/src/composition/use-click-outside.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { Ref } from 'vue'; -import { useGlobalEvent } from './use-global-event'; - -export type UseClickOutsideOpitons = { - event: string; - callback: EventListener; - element: Ref; - flag?: Ref; -}; - -export function useClickOutside(options: UseClickOutsideOpitons) { - const { event = 'click', callback, element, flag } = options; - - function onClick(event: Event) { - if (!element.value.contains(event.target as Node)) { - callback(event); - } - } - - useGlobalEvent(document, event, onClick, false, flag); -} diff --git a/src/composition/use-global-event.ts b/src/composition/use-global-event.ts deleted file mode 100644 index 6d227742f..000000000 --- a/src/composition/use-global-event.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { on, off } from '../utils/dom/event'; -import { - Ref, - unref, - watch, - onMounted, - onActivated, - onUnmounted, - onDeactivated, -} from 'vue'; - -export function useGlobalEvent( - target: EventTarget | Ref, - event: string, - handler: EventListener, - passive = false, - flag?: Ref -) { - let binded: boolean; - - const add = () => { - const element = unref(target); - - if (binded || (flag && !flag.value) || !element) { - return; - } - - on(element, event, handler, passive); - binded = true; - }; - - const remove = () => { - const element = unref(target); - if (binded && element) { - off(element, event, handler); - binded = false; - } - }; - - if (flag) { - watch(flag, () => { - flag.value ? add() : remove(); - }); - } - - onMounted(add); - onActivated(add); - onUnmounted(remove); - onDeactivated(remove); -} diff --git a/src/dropdown-menu/index.js b/src/dropdown-menu/index.js index 385c46452..ad060d9b0 100644 --- a/src/dropdown-menu/index.js +++ b/src/dropdown-menu/index.js @@ -4,10 +4,9 @@ import { ref, provide, reactive, computed } from 'vue'; import { createNamespace, isDef } from '../utils'; // Composition -import { useEventListener } from '@vant/use'; +import { useClickAway, useEventListener } from '@vant/use'; import { useRect } from '../composition/use-rect'; import { useScroller } from '../composition/use-scroller'; -import { useClickOutside } from '../composition/use-click-outside'; const [createComponent, bem] = createNamespace('dropdown-menu'); @@ -55,7 +54,7 @@ export default createComponent({ } }); - const onClickOutside = () => { + const onClickAway = () => { children.forEach((item) => { item.toggle(false); }); @@ -122,10 +121,7 @@ export default createComponent({ provide(DROPDOWN_KEY, { props, offset, children }); - useClickOutside({ - element: rootRef, - callback: onClickOutside, - }); + useClickAway(rootRef, onClickAway); useEventListener('scroll', onScroll, { target: scroller }); diff --git a/src/number-keyboard/index.js b/src/number-keyboard/index.js index b093afae7..4f0c22c26 100644 --- a/src/number-keyboard/index.js +++ b/src/number-keyboard/index.js @@ -1,7 +1,7 @@ import { ref, watch, computed, Teleport, Transition } from 'vue'; import { createNamespace } from '../utils'; import { stopPropagation } from '../utils/dom/event'; -import { useClickOutside } from '../composition/use-click-outside'; +import { useClickAway } from '@vant/use'; import Key from './Key'; const [createComponent, bem] = createNamespace('number-keyboard'); @@ -224,11 +224,7 @@ export default createComponent({ } ); - useClickOutside({ - event: 'touchstart', - element: rootRef, - callback: onClose, - }); + useClickAway(rootRef, onClose, { eventName: 'touchstart' }); return () => { const Title = renderTitle(); diff --git a/src/swipe-cell/index.js b/src/swipe-cell/index.js index 1ff677e15..d342b7a54 100644 --- a/src/swipe-cell/index.js +++ b/src/swipe-cell/index.js @@ -7,10 +7,10 @@ import { preventDefault } from '../utils/dom/event'; import { callInterceptor } from '../utils/interceptor'; // Composition +import { useClickAway } from '@vant/use'; import { useRect } from '../composition/use-rect'; import { useTouch } from '../composition/use-touch'; import { usePublicApi } from '../composition/use-public-api'; -import { useClickOutside } from '../composition/use-click-outside'; const [createComponent, bem] = createNamespace('swipe-cell'); @@ -183,11 +183,7 @@ export default createComponent({ close, }); - useClickOutside({ - element: rootRef, - event: 'touchstart', - callback: onClick, - }); + useClickAway(rootRef, onClick, { eventName: 'touchstart' }); return () => { const wrapperStyle = {