mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-09-04 15:09:45 +08:00
fix(List): skip check when inside an inactive tab (#8741)
This commit is contained in:
parent
62a30bbf02
commit
38aeecfcb7
8
src/composables/use-tab-status.ts
Normal file
8
src/composables/use-tab-status.ts
Normal 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);
|
||||||
|
}
|
@ -14,6 +14,7 @@ import { isHidden, truthProp, createNamespace } from '../utils';
|
|||||||
// Composables
|
// Composables
|
||||||
import { useRect, useScrollParent, useEventListener } from '@vant/use';
|
import { useRect, useScrollParent, useEventListener } from '@vant/use';
|
||||||
import { useExpose } from '../composables/use-expose';
|
import { useExpose } from '../composables/use-expose';
|
||||||
|
import { useTabStatus } from '../composables/use-tab-status';
|
||||||
|
|
||||||
// Components
|
// Components
|
||||||
import { Loading } from '../loading';
|
import { Loading } from '../loading';
|
||||||
@ -50,11 +51,18 @@ export default defineComponent({
|
|||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
const root = ref<HTMLElement>();
|
const root = ref<HTMLElement>();
|
||||||
const placeholder = ref<HTMLElement>();
|
const placeholder = ref<HTMLElement>();
|
||||||
|
const tabStatus = useTabStatus();
|
||||||
const scrollParent = useScrollParent(root);
|
const scrollParent = useScrollParent(root);
|
||||||
|
|
||||||
const check = () => {
|
const check = () => {
|
||||||
nextTick(() => {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,7 +70,7 @@ export default defineComponent({
|
|||||||
const scrollParentRect = useRect(scrollParent);
|
const scrollParentRect = useRect(scrollParent);
|
||||||
|
|
||||||
if (!scrollParentRect.height || isHidden(root)) {
|
if (!scrollParentRect.height || isHidden(root)) {
|
||||||
return false;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let isReachEdge = false;
|
let isReachEdge = false;
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
import { List } from '..';
|
import { List } from '..';
|
||||||
|
import { Tab } from '../../tab';
|
||||||
|
import { Tabs } from '../../tabs';
|
||||||
import { mount, later, mockGetBoundingClientRect } from '../../../test';
|
import { mount, later, mockGetBoundingClientRect } from '../../../test';
|
||||||
|
|
||||||
test('should emit load event when reaching bottom', async () => {
|
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[0].classes()).toContain('list-item');
|
||||||
expect(children[1].classes()).toContain('van-list__placeholder');
|
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);
|
||||||
|
});
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
import {
|
import {
|
||||||
ref,
|
ref,
|
||||||
watch,
|
watch,
|
||||||
|
provide,
|
||||||
|
computed,
|
||||||
nextTick,
|
nextTick,
|
||||||
PropType,
|
PropType,
|
||||||
CSSProperties,
|
CSSProperties,
|
||||||
@ -14,6 +16,7 @@ import { TABS_KEY, TabsProvide } from '../tabs/Tabs';
|
|||||||
// Composables
|
// Composables
|
||||||
import { useParent } from '@vant/use';
|
import { useParent } from '@vant/use';
|
||||||
import { routeProps } from '../composables/use-route';
|
import { routeProps } from '../composables/use-route';
|
||||||
|
import { TAB_STATUS_KEY } from '../composables/use-tab-status';
|
||||||
|
|
||||||
// Components
|
// Components
|
||||||
import { SwipeItem } from '../swipe-item';
|
import { SwipeItem } from '../swipe-item';
|
||||||
@ -56,15 +59,15 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const isActive = () => {
|
const active = computed(() => {
|
||||||
const active = getName() === parent.currentName.value;
|
const isActive = getName() === parent.currentName.value;
|
||||||
|
|
||||||
if (active && !inited.value) {
|
if (isActive && !inited.value) {
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
return active;
|
return isActive;
|
||||||
};
|
});
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.title,
|
() => props.title,
|
||||||
@ -74,6 +77,8 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
provide(TAB_STATUS_KEY, active);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
const { animated, swipeable, scrollspy, lazyRender } = parent.props;
|
const { animated, swipeable, scrollspy, lazyRender } = parent.props;
|
||||||
|
|
||||||
@ -81,15 +86,14 @@ export default defineComponent({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const active = isActive();
|
const show = scrollspy || active.value;
|
||||||
const show = scrollspy || active;
|
|
||||||
|
|
||||||
if (animated || swipeable) {
|
if (animated || swipeable) {
|
||||||
return (
|
return (
|
||||||
<SwipeItem
|
<SwipeItem
|
||||||
role="tabpanel"
|
role="tabpanel"
|
||||||
aria-hidden={!active}
|
aria-hidden={!active.value}
|
||||||
class={bem('pane-wrapper', { inactive: !active })}
|
class={bem('pane-wrapper', { inactive: !active.value })}
|
||||||
>
|
>
|
||||||
<div class={bem('pane')}>{slots.default?.()}</div>
|
<div class={bem('pane')}>{slots.default?.()}</div>
|
||||||
</SwipeItem>
|
</SwipeItem>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user