mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-06 03:57:59 +08:00
feat(use): add useClickAway
This commit is contained in:
parent
a58da5570b
commit
195f3ffea1
@ -1,2 +1,3 @@
|
||||
export { useToggle } from './useToggle';
|
||||
export { useClickAway } from './useClickAway';
|
||||
export { useEventListener } from './useEventListener';
|
||||
|
27
packages/vant-use/src/useClickAway/index.ts
Normal file
27
packages/vant-use/src/useClickAway/index.ts
Normal file
@ -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<Element>,
|
||||
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 });
|
||||
}
|
@ -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;
|
||||
|
@ -1,21 +0,0 @@
|
||||
import { Ref } from 'vue';
|
||||
import { useGlobalEvent } from './use-global-event';
|
||||
|
||||
export type UseClickOutsideOpitons = {
|
||||
event: string;
|
||||
callback: EventListener;
|
||||
element: Ref<Element>;
|
||||
flag?: Ref<boolean>;
|
||||
};
|
||||
|
||||
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);
|
||||
}
|
@ -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<EventTarget>,
|
||||
event: string,
|
||||
handler: EventListener,
|
||||
passive = false,
|
||||
flag?: Ref<boolean>
|
||||
) {
|
||||
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);
|
||||
}
|
@ -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 });
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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 = {
|
||||
|
Loading…
x
Reference in New Issue
Block a user