diff --git a/packages/vant/src/composables/use-tab-status.ts b/packages/vant/src/composables/use-tab-status.ts index 4f66f8794..ba7f1e34f 100644 --- a/packages/vant/src/composables/use-tab-status.ts +++ b/packages/vant/src/composables/use-tab-status.ts @@ -1,6 +1,21 @@ -import { inject, ComputedRef, InjectionKey } from 'vue'; +import { inject, ComputedRef, InjectionKey, provide, computed } from 'vue'; -// eslint-disable-next-line export const TAB_STATUS_KEY: InjectionKey> = Symbol(); +export const ALL_TAB_STATUS_KEY: InjectionKey> = Symbol(); + export const useTabStatus = () => inject(TAB_STATUS_KEY, null); + +export const useAllTabStatus = () => inject(ALL_TAB_STATUS_KEY, null); + +export const useProvideTabStatus = (status: ComputedRef) => { + const allTabStatus = useAllTabStatus(); + provide(TAB_STATUS_KEY, status); + + provide( + ALL_TAB_STATUS_KEY, + computed(() => { + return (allTabStatus == null || allTabStatus.value) && status.value; + }), + ); +}; diff --git a/packages/vant/src/list/List.tsx b/packages/vant/src/list/List.tsx index 49abda497..cc5b1dd9f 100644 --- a/packages/vant/src/list/List.tsx +++ b/packages/vant/src/list/List.tsx @@ -22,7 +22,7 @@ import { // Composables import { useRect, useScrollParent, useEventListener } from '@vant/use'; import { useExpose } from '../composables/use-expose'; -import { useTabStatus } from '../composables/use-tab-status'; +import { useAllTabStatus } from '../composables/use-tab-status'; // Components import { Loading } from '../loading'; @@ -60,7 +60,7 @@ export default defineComponent({ const loading = ref(props.loading); const root = ref(); const placeholder = ref(); - const tabStatus = useTabStatus(); + const tabStatus = useAllTabStatus(); const scrollParent = useScrollParent(root); const scroller = computed(() => props.scroller || scrollParent.value); diff --git a/packages/vant/src/tab/README.md b/packages/vant/src/tab/README.md index c4e58cd8b..2063c787c 100644 --- a/packages/vant/src/tab/README.md +++ b/packages/vant/src/tab/README.md @@ -385,3 +385,16 @@ For example, the following code: ``` This is because the `fixed` positioning inside the `transform` element is computed relative to that element, not relative to the entire document, resulting in layout exceptions. + +### How to determine if the current component is inside an active Tab? + +In a child component, you can use `useTabStatus` or `useAllTabStatus` to check whether the component is inside an active `Tab`. + +- `useTabStatus`: Returns whether the current component's parent `Tab` is active. Returns `null` if the component is not inside a `Tab`. +- `useAllTabStatus`: In nested Tab scenarios, returns whether all parent `Tabs` are active. Returns `null` if the component is not inside a `Tab`. + +```js +const isActive = useTabStatus(); +// For nested Tab scenarios +const isAllActive = useAllTabStatus(); +``` diff --git a/packages/vant/src/tab/README.zh-CN.md b/packages/vant/src/tab/README.zh-CN.md index 9cea95753..d9e01052b 100644 --- a/packages/vant/src/tab/README.zh-CN.md +++ b/packages/vant/src/tab/README.zh-CN.md @@ -423,3 +423,16 @@ this.$refs.tabs.resize(); ``` 这是因为 `transform` 元素内部的 `fixed` 定位会相对于该元素进行计算,而不是相对于整个文档,从而导致布局异常。 + +### 如何判断当前组件是否处于激活的 Tab 内? + +可以在子组件中通过调用 `useTabStatus` 或 `useAllTabStatus` 来判断当前组件是否处于激活的 `Tab` 内部。 + +- `useTabStatus`:返回当前组件所在的 `Tab` 是否为激活状态,若组件不在 `Tab` 内部则返回 `null`。 +- `useAllTabStatus`:在存在嵌套 `Tab` 的场景下,返回是否所有上层 `Tab` 为激活状态,若组件不在 `Tab` 内部则返回 `null`。 + +```js +const isActive = useTabStatus(); +// 嵌套 Tab 场景 +const isAllActive = useAllTabStatus(); +``` diff --git a/packages/vant/src/tab/Tab.tsx b/packages/vant/src/tab/Tab.tsx index 2d4bc49f1..51ea5d027 100644 --- a/packages/vant/src/tab/Tab.tsx +++ b/packages/vant/src/tab/Tab.tsx @@ -1,7 +1,6 @@ import { ref, watch, - provide, computed, nextTick, watchEffect, @@ -31,7 +30,7 @@ import { doubleRaf, useParent } from '@vant/use'; import { useId } from '../composables/use-id'; import { useExpose } from '../composables/use-expose'; import { routeProps } from '../composables/use-route'; -import { TAB_STATUS_KEY } from '../composables/use-tab-status'; +import { useProvideTabStatus } from '../composables/use-tab-status'; // Components import { TabTitle } from './TabTitle'; @@ -154,7 +153,7 @@ export default defineComponent({ }, ); - provide(TAB_STATUS_KEY, active); + useProvideTabStatus(active); useExpose({ id, diff --git a/packages/vant/src/tab/index.ts b/packages/vant/src/tab/index.ts index a5d10c3c5..2927b71fa 100644 --- a/packages/vant/src/tab/index.ts +++ b/packages/vant/src/tab/index.ts @@ -4,6 +4,7 @@ import _Tab from './Tab'; export const Tab = withInstall(_Tab); export default Tab; export { tabProps } from './Tab'; +export { useTabStatus, useAllTabStatus } from '../composables/use-tab-status'; export type { TabProps } from './Tab'; declare module 'vue' {