fix(List): skip check when inside an inactive tab (#8741)

This commit is contained in:
neverland 2021-05-22 17:38:05 +08:00 committed by GitHub
parent 62a30bbf02
commit 38aeecfcb7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 55 additions and 11 deletions

View File

@ -0,0 +1,8 @@
import { inject, ComputedRef } from 'vue';
// eslint-disable-next-line
export const TAB_STATUS_KEY = Symbol();
export function useTabStatus() {
return inject<ComputedRef<boolean> | null>(TAB_STATUS_KEY, null);
}

View File

@ -14,6 +14,7 @@ import { isHidden, truthProp, createNamespace } from '../utils';
// Composables
import { useRect, useScrollParent, useEventListener } from '@vant/use';
import { useExpose } from '../composables/use-expose';
import { useTabStatus } from '../composables/use-tab-status';
// Components
import { Loading } from '../loading';
@ -50,11 +51,18 @@ export default defineComponent({
const loading = ref(false);
const root = ref<HTMLElement>();
const placeholder = ref<HTMLElement>();
const tabStatus = useTabStatus();
const scrollParent = useScrollParent(root);
const check = () => {
nextTick(() => {
if (loading.value || props.finished || props.error) {
if (
loading.value ||
props.finished ||
props.error ||
// skip check when inside an inactive tab
tabStatus?.value === false
) {
return;
}
@ -62,7 +70,7 @@ export default defineComponent({
const scrollParentRect = useRect(scrollParent);
if (!scrollParentRect.height || isHidden(root)) {
return false;
return;
}
let isReachEdge = false;

View File

@ -1,4 +1,6 @@
import { List } from '..';
import { Tab } from '../../tab';
import { Tabs } from '../../tabs';
import { mount, later, mockGetBoundingClientRect } from '../../../test';
test('should emit load event when reaching bottom', async () => {
@ -134,3 +136,25 @@ test('should render correctly when direction is up', async () => {
expect(children[0].classes()).toContain('list-item');
expect(children[1].classes()).toContain('van-list__placeholder');
});
test('should not emit load event when inside an inactive tab', async () => {
const onLoad1 = jest.fn();
const onLoad2 = jest.fn();
mount({
render: () => (
<Tabs active={0} animated>
<Tab>
<List onLoad={onLoad1} />
</Tab>
<Tab>
<List onLoad={onLoad2} />
</Tab>
</Tabs>
),
});
await later();
expect(onLoad1).toHaveBeenCalledTimes(1);
expect(onLoad2).toHaveBeenCalledTimes(0);
});

View File

@ -1,6 +1,8 @@
import {
ref,
watch,
provide,
computed,
nextTick,
PropType,
CSSProperties,
@ -14,6 +16,7 @@ import { TABS_KEY, TabsProvide } from '../tabs/Tabs';
// Composables
import { useParent } from '@vant/use';
import { routeProps } from '../composables/use-route';
import { TAB_STATUS_KEY } from '../composables/use-tab-status';
// Components
import { SwipeItem } from '../swipe-item';
@ -56,15 +59,15 @@ export default defineComponent({
}
};
const isActive = () => {
const active = getName() === parent.currentName.value;
const active = computed(() => {
const isActive = getName() === parent.currentName.value;
if (active && !inited.value) {
if (isActive && !inited.value) {
init();
}
return active;
};
return isActive;
});
watch(
() => props.title,
@ -74,6 +77,8 @@ export default defineComponent({
}
);
provide(TAB_STATUS_KEY, active);
return () => {
const { animated, swipeable, scrollspy, lazyRender } = parent.props;
@ -81,15 +86,14 @@ export default defineComponent({
return;
}
const active = isActive();
const show = scrollspy || active;
const show = scrollspy || active.value;
if (animated || swipeable) {
return (
<SwipeItem
role="tabpanel"
aria-hidden={!active}
class={bem('pane-wrapper', { inactive: !active })}
aria-hidden={!active.value}
class={bem('pane-wrapper', { inactive: !active.value })}
>
<div class={bem('pane')}>{slots.default?.()}</div>
</SwipeItem>