diff --git a/src/collapse-item/index.js b/src/collapse-item/index.js
index 1340dc2b4..57dadf2bd 100644
--- a/src/collapse-item/index.js
+++ b/src/collapse-item/index.js
@@ -41,7 +41,7 @@ export default createComponent({
});
const show = ref(expanded.value);
- const shouldRender = useLazyRender(show);
+ const lazyRender = useLazyRender(show);
const onTransitionEnd = () => {
if (!expanded.value) {
@@ -115,22 +115,18 @@ export default createComponent({
);
};
- const renderContent = () => {
- if (shouldRender.value) {
- return (
-
-
- {slots.default?.()}
-
-
- );
- }
- };
+ const renderContent = lazyRender(() => (
+
+
+ {slots.default?.()}
+
+
+ ));
return () => (
diff --git a/src/composition/use-lazy-render.ts b/src/composition/use-lazy-render.ts
index 26e902cd2..dcecc2771 100644
--- a/src/composition/use-lazy-render.ts
+++ b/src/composition/use-lazy-render.ts
@@ -1,13 +1,17 @@
-import { ref, isRef, watch, WatchSource } from 'vue';
+import { ref, watch, WatchSource, VNode } from 'vue';
export function useLazyRender(show: WatchSource
) {
- const inited = ref(isRef(show) ? show.value : show());
+ const inited = ref(false);
- watch(show, (value) => {
- if (value) {
- inited.value = value;
- }
- });
+ watch(
+ show,
+ (value) => {
+ if (value) {
+ inited.value = value;
+ }
+ },
+ { immediate: true }
+ );
- return inited;
+ return (render: () => VNode) => () => (inited.value ? render() : null);
}
diff --git a/src/composition/use-lock-scroll.ts b/src/composition/use-lock-scroll.ts
index 41d2da242..c64e9edf6 100644
--- a/src/composition/use-lock-scroll.ts
+++ b/src/composition/use-lock-scroll.ts
@@ -1,55 +1,25 @@
-import { useTouch } from './use-touch';
-import { getScroller } from '../utils/dom/scroll';
-import { on, off, preventDefault } from '../utils/dom/event';
-
let count = 0;
+
const CLASSNAME = 'van-overflow-hidden';
-export function useLockScroll(element: HTMLElement) {
- const { start, move, deltaY, direction } = useTouch();
-
- const onTouchMove = ((event: TouchEvent) => {
- move(event);
-
- if (direction.value !== 'vertical') {
- return;
- }
-
- let prevent = false;
- const up = deltaY.value < 0;
- const scroller = getScroller(event.target as HTMLElement, element);
- const { scrollTop, scrollHeight, offsetHeight } = scroller as HTMLElement;
-
- if (scrollTop === 0) {
- prevent = up && offsetHeight < scrollHeight;
- } else if (scrollTop + offsetHeight >= scrollHeight) {
- prevent = !up;
- }
-
- if (prevent) {
- preventDefault(event, true);
- }
- }) as EventListener;
-
+export function useLockScroll(shouldLock: () => boolean) {
const lock = () => {
- if (!count) {
- document.body.classList.add(CLASSNAME);
- }
-
- count++;
- on(document, 'touchstart', start);
- on(document, 'touchmove', onTouchMove);
- };
-
- lock();
-
- return function unlock() {
- count--;
- off(document, 'touchstart', start);
- off(document, 'touchmove', onTouchMove);
-
- if (!count) {
- document.body.classList.remove(CLASSNAME);
+ if (shouldLock()) {
+ if (!count) {
+ document.body.classList.add(CLASSNAME);
+ }
+ count++;
}
};
+
+ const unlock = () => {
+ if (shouldLock() && count) {
+ count--;
+ if (!count) {
+ document.body.classList.remove(CLASSNAME);
+ }
+ }
+ };
+
+ return [lock, unlock];
}
diff --git a/src/popup/index.js b/src/popup/index.js
index fadbdaac1..34b5daeeb 100644
--- a/src/popup/index.js
+++ b/src/popup/index.js
@@ -3,6 +3,7 @@ import {
ref,
watch,
Teleport,
+ computed,
onMounted,
Transition,
onActivated,
@@ -12,6 +13,7 @@ import {
import { createNamespace, isDef } from '../utils';
// Composition
+import { useLockScroll } from '../composition/use-lock-scroll';
import { useLazyRender } from '../composition/use-lazy-render';
import { CloseOnPopstateMixin } from '../mixins/close-on-popstate';
@@ -106,39 +108,36 @@ export default createComponent({
const zIndex = ref();
- const shouldRender = useLazyRender(() => props.show || !props.lazyRender);
+ const [lockScroll, unlockScroll] = useLockScroll(() => props.lockScroll);
- const lockScroll = () => {
- if (props.lockScroll) {
- if (!context.lockCount) {
- document.body.classList.add('van-overflow-hidden');
- }
- context.lockCount++;
+ const lazyRender = useLazyRender(() => props.show || !props.lazyRender);
+
+ const style = computed(() => {
+ const style = {
+ zIndex: zIndex.value,
+ };
+
+ if (isDef(props.duration)) {
+ const key =
+ props.position === 'center'
+ ? 'animationDuration'
+ : 'transitionDuration';
+ style[key] = `${props.duration}s`;
}
- };
- const unlockScroll = () => {
- if (props.lockScroll && context.lockCount) {
- context.lockCount--;
-
- if (!context.lockCount) {
- document.body.classList.remove('van-overflow-hidden');
- }
- }
- };
+ return style;
+ });
const open = () => {
- if (opened) {
- return;
- }
+ if (!opened) {
+ if (props.zIndex !== undefined) {
+ context.zIndex = props.zIndex;
+ }
- if (props.zIndex !== undefined) {
- context.zIndex = props.zIndex;
+ opened = true;
+ lockScroll();
+ zIndex.value = ++context.zIndex;
}
-
- opened = true;
- lockScroll();
- zIndex.value = ++context.zIndex;
};
const close = () => {
@@ -151,7 +150,6 @@ export default createComponent({
const onClickOverlay = () => {
emit('click-overlay');
-
if (props.closeOnClickOverlay) {
close();
}
@@ -190,50 +188,38 @@ export default createComponent({
const onOpened = () => emit('opened');
const onClosed = () => emit('closed');
- const renderPopup = () => {
- const {
- round,
- position,
- duration,
- transition,
- safeAreaInsetBottom,
- } = props;
- const isCenter = position === 'center';
+ const renderPopup = lazyRender(() => {
+ const { round, position, safeAreaInsetBottom } = props;
+ return (
+
+ {slots.default?.()}
+ {renderCloseIcon()}
+
+ );
+ });
- const transitionName =
- transition || (isCenter ? 'van-fade' : `van-popup-slide-${position}`);
-
- const style = {
- zIndex: zIndex.value,
- };
-
- if (isDef(duration)) {
- const key = isCenter ? 'animationDuration' : 'transitionDuration';
- style[key] = `${duration}s`;
- }
+ const renderTransition = () => {
+ const { position, transition } = props;
+ const name =
+ position === 'center' ? 'van-fade' : `van-popup-slide-${position}`;
return (
- {shouldRender.value ? (
-
- {slots.default?.()}
- {renderCloseIcon()}
-
- ) : null}
+ {renderPopup()}
);
};
@@ -282,7 +268,7 @@ export default createComponent({
return (
{renderOverlay()}
- {renderPopup()}
+ {renderTransition()}
);
}
@@ -290,7 +276,7 @@ export default createComponent({
return (
<>
{renderOverlay()}
- {renderPopup()}
+ {renderTransition()}
>
);
};