我有一个使用选项卡模板 (
npx create-expo-app --template tabs
) 的博览会项目,目标是本机和网络。
对于这个例子,假设我有三页:
文件夹如下所示:
(tabs)
│ _layout.tsx
│ explore.tsx
│ favorites.tsx
│
details
│ _layout.tsx
│ [id].tsx
│
_layout.tsx
当我在探索或收藏夹页面中单击某个项目时,我希望能够从这两个页面链接到详细信息页面。但是,这会导致页面在选项卡导航顶部打开。我想在选项卡堆栈的上下文中打开它,保持选项卡导航可见。
现在我知道如果我像这样构造我的代码它会起作用:
(tabs)
│ _layout.tsx
│
└── explore
│ │ _layout.tsx
│ │ index.tsx
│ │ [id].tsx <- Details page
│
└── favorites
│ │ _layout.tsx
│ │ index.tsx
│ │ [id].tsx <- Details page
│
_layout.tsx
但这会导致网络出现重复的路由:
/explore/test-item
和/favorites/test-item
。这也使得与它们进行深度链接变得困难。我研究了共享路线,但我无法理解它们在这种情况下如何工作(在我的项目中,路线的嵌套方式不同,所以它更像是/profile/favorites/
和/explore/
)两者都需要在各自的堆栈中打开 /details/test-item/
我正在使用 <Stack>
提供的 expo-router
组件,它没有 component
中的 react-navigation
属性。
我找到了一个有效的解决方案(有一个小警告 - 见下文)。
使用 共享路由 将所有顶级选项卡路由和嵌套共享路由分组在一起,然后使用
_layout.tsx
的 segment
属性指定当前活动选项卡的顶级路由。
考虑一个具有三个选项卡(主页、搜索和库)的应用程序,以及一个需要在每个选项卡堆栈中显示的嵌套项目屏幕。
首先设置以下文件结构:
app/
├── _layout.tsx // defines root stack with single (tabs) screen
└── (tabs)/
├── _layout.tsx
└── (home,search,library)/
├── _layout.tsx
├── index.tsx
├── search.tsx
├── library.tsx
└── item.tsx // This is a nested shared route and not a tab
在您的(选项卡)
_layout.tsx
文件中,确保每个选项卡指向相关组:
<Tabs screenOptions={{ headerShown: false }} >
<Tabs.Screen name="(home)" options={{ title: 'Home' }} />
<Tabs.Screen name="(search)" options={{ title: 'Search' }} />
<Tabs.Screen name="(library)" options={{ title: 'Your Library' }} />
</Tabs>
然后,在您的(家庭、搜索、图书馆)共享路径
_layout.tsx
文件中,使用 segment
属性打开每个段并为每个选项卡定义每个根堆栈屏幕:
const Layout = ({ segment }) => {
const rootScreen = useMemo(() => {
switch (segment) {
case '(home)':
return <Stack.Screen name="index" options={{ title: 'Home' }} />
case '(search)':
return <Stack.Screen name="search" options={{ title: 'Search' }} />
case '(library)':
return <Stack.Screen name="library" options={{ title: 'Your Library' }} />
}
}, [segment])
return (
<Stack>
{rootScreen}
<Stack.Screen name="item" options={{ title: 'Item' }} />
</Stack>
)
}
export default Layout
“共享路线”功能本质上是定义三个组中每一个组的“速记”。上面定义的文件结构使用这个“简写”,并且等同于:
app/
├── _layout.tsx // defines root stack with single (tabs) screen
└── (tabs)/
├── _layout.tsx
├── (home)/
│ ├── _layout.tsx
│ ├── index.tsx
│ └── item.tsx
├── (search)/
│ ├── _layout.tsx
│ ├── search.tsx
│ └── item.tsx
└── (library)/
├── _layout.tsx
├── library.tsx
└── item.tsx
影响
/item
推到当前堆栈上✅ 导航到
(search)/item
选项卡访问此目录中的所有嵌套屏幕。这在实践中可能不是问题,但值得注意。