Expo Router 中基于文件路由的核心概念
了解 Expo Router 的基本规则以及它与其他代码的关系。
在深入研究如何使用 Expo Router 构建应用的导航树之前,让我们首先了解构成 Expo Router 中基于文件路由基础的核心概念,以及 Expo Router 项目在结构上与其他 React Native 项目有何不同。
🌐 Before diving into how to construct your app's navigation tree with Expo Router, let's first understand the core concepts that make up the foundation of file-based routing in Expo Router, and how an Expo Router project might differ in structure from other React Native projects.
Expo Router 规则
🌐 The rules of Expo Router
1. 所有屏幕/页面都是 src/app 目录下的文件
🌐 1. All screens/pages are files inside the src/app directory
你应用中的所有导航路径都由 src/app 目录中的文件和子目录定义。src/app 目录中的每个文件都有一个默认导出,用于定义应用中的一个独立页面(特殊的 _layout 文件除外)。
🌐 All navigation routes in your app are defined by the files and sub-directories inside the src/app directory. Every file inside the src/app directory has a default export that defines a distinct page in your app (except for the special _layout files).
因此,src/app 内的目录将相关的屏幕组合在一起定义。
🌐 Accordingly, directories inside src/app define groups of related screens together.
2. 所有页面都有一个网址
🌐 2. All pages have a URL
所有页面都有一个 URL 路径,该路径与 src/app 目录中文件的位置相匹配,可用于在网页地址栏中导航到该页面,或作为原生移动应用中的特定应用深层链接。这就是 Expo Router 支持通用深层链接的意思。无论平台如何,你的应用中的所有页面都可以通过 URL 进行导航。
🌐 All pages have a URL path that matches the file's location in the src/app directory, which can be used to navigate to that page in the address bar on the web, or as an app-specific deep link in a native mobile app. This is what is meant by Expo Router supporting universal deep-linking. All pages in your app can be navigated to with a URL, regardless of the platform.
3. 首先,index.tsx 是初始路由
🌐 3. First index.tsx is the initial route
使用 Expo Router 时,你不需要在代码中定义初始路由或第一个屏幕。相反,当你打开应用时,Expo Router 会寻找与 / URL 匹配的第一个 index.tsx 文件。在默认模板中,这个文件是 src/app/index.tsx。如果应用用户默认应从导航树的更深层开始,你可以使用路由组(一个名称被括号包围的目录),这不会算作 URL 的一部分。如果你希望第一个屏幕是一个选项卡组,可以将所有选项卡页面放在 src/app/(tabs) 目录下,并将默认选项卡定义为 index.tsx。通过这种安排,/ URL 会直接将用户带到 src/app/(tabs)/index.tsx 文件。
🌐 With Expo Router, you do not define an initial route or first screen in code. Rather, when you open your app, Expo Router will look for the first index.tsx file matching the / URL. In the default template, this is src/app/index.tsx. If the app user should start by default in a deeper part of your navigation tree, you can use a route group (a directory where the name is surrounded in parentheses), and that will not count as part of the URL. If you want your first screen to be a group of tabs, you might put all of the tab pages inside the src/app/(tabs) directory and define the default tab as index.tsx. With this arrangement, the / URL will take the user directly to src/app/(tabs)/index.tsx file.
4. Root _layout.tsx 取代 App.jsx/tsx
🌐 4. Root _layout.tsx replaces App.jsx/tsx
每个项目都应该在 src/app 目录下直接有一个 _layout.tsx 文件。这个文件会在应用中的任何其他路由之前渲染,并且是你放置初始化代码的地方,这些代码以前可能会放在 App.jsx 文件中,例如加载字体、设置主题提供程序或与启动画面交互。例如,默认模板会使用 ThemeProvider 封装应用以支持暗色和亮色模式,并从此文件渲染 AppTabs 组件。
🌐 Every project should have a _layout.tsx file directly inside the src/app directory. This file is rendered before any other route in your app and is where you would put the initialization code that may have previously gone inside an App.jsx file, such as loading fonts, setting up theme providers, or interacting with the splash screen. For example, the default template wraps the app with a ThemeProvider for dark and light mode support and renders the AppTabs component from this file.
5. 默认模板使用平台特定的选项卡
🌐 5. Default template uses platform-specific tabs
默认模板根据不同的平台使用两种不同的标签实现。在 Android 和 iOS 上,标签使用 原生标签 渲染,这些标签使用平台内置的标签栏,以获得原生的外观和感觉。在 Web 上,标签使用来自 expo-router/ui 的 自定义标签 渲染,这些标签是无样式的灵活组件,允许完全控制标签栏的外观。
🌐 The default template uses two different tab implementations depending on the platform. On Android and iOS, tabs are rendered using native tabs, which use the platform's built-in tab bar for a native look and feel. On web, tabs are rendered using custom tabs from expo-router/ui, which are unstyled and flexible components that allow full control over the tab bar's appearance.
这是通过特定平台的文件扩展名实现的。标签页组件在两个文件中定义:src/components/app-tabs.native.tsx 用于 Android 和 iOS,src/components/app-tabs.tsx 用于 Web。Expo 的模块解析会根据平台自动选择正确的文件。使用这种模式是因为原生平台有一个系统标签栏,可以提供预期的行为,如点击返回顶部和原生动画,而 Web 则需要一个符合典型网站导航模式的自定义样式标签栏。
🌐 This is achieved through platform-specific file extensions. The tab component is defined in two files: src/components/app-tabs.native.tsx for Android and iOS, and src/components/app-tabs.tsx for web. Expo's module resolution automatically picks the correct file based on the platform. This pattern is used because native platforms have a system tab bar that provides expected behaviors like scroll-to-top on tap and native animations, while web requires a custom-styled tab bar that fits typical website navigation patterns.
6. 非导航组件位于 src/app 目录之外
🌐 6. Non-navigation components live outside the src/app directory
在 Expo Router 中,src/app 目录专门用于定义应用的路由。应用的其他部分,如组件、hooks、工具等,应放在其他目录中,例如 src/components、src/hooks 和 src/constants。如果你将非路由文件放入 src/app 目录,Expo Router 会尝试将其当作路由来处理。
🌐 In Expo Router, the src/app directory is exclusively for defining your app's routes. Other parts of your app, like components, hooks, utilities, and so on, should be placed in other directories such as src/components, src/hooks, and src/constants. If you put a non-route inside the src/app directory, Expo Router will attempt to treat it like a route.
7. 在底层,它仍然是 React Navigation
🌐 7. It's still React Navigation under the hood
虽然这听起来与 React Navigation 有很大不同,但 Expo Router 实际上是建立在 React Navigation 之上的。你可以把 Expo Router 看作是一种 Expo CLI 的优化,它将你的文件结构转换为你之前在代码中定义的 React Navigation 组件。
🌐 While this may sound quite a bit different from React Navigation, Expo Router is actually built on top of React Navigation. You can think of Expo Router as an Expo CLI optimization that translates your file structure into React Navigation components that you previously defined in your own code.
这也意味着你可以经常参考 React Navigation 文档来了解如何设置或配置导航,因为默认的堆栈导航器和标签导航器使用完全相同的选项。
🌐 This also means that you can often refer to React Navigation documentation for how to style or configure navigation, as the default stack and tab navigators use the exact same options.
Expo Router 规则的应用
🌐 The rules of Expo Router applied
让我们运用 Expo Router 的基本规则来快速识别以下项目文件结构的关键元素:
🌐 Let's apply these foundational rules of Expo Router to quickly identify key elements of the following project file structure:
srcappindex.tsxhome.tsx_layout.tsxprofilefriends.tsxcomponentsapp-tabs.native.tsxapp-tabs.tsxtext-field.tsxtoolbar.tsx- src/app/index.tsx 是初始路由,当你打开应用或导航到你的网络应用的根 URL 时,它将首先出现。
- src/app/home.tsx 是一个路径为
/home的页面,所以你可以在浏览器中通过yourapp.com/home这样的 URL 访问它,或者在原生应用中通过yourapp://home访问它。 - src/app/_layout.tsx 是根布局。你之前可能放在 App.jsx 中的任何初始化代码都应该放在这里。
- src/app/profile/friends.tsx 是一个路由为
/profile/friends的页面。 - src/components/app-tabs.native.tsx 和 src/components/app-tabs.tsx 是特定平台的标签组件。.native.tsx 文件用于 Android 和 iOS,而 .tsx 文件用于网页。根布局导入这些文件以渲染标签导航器。
- src/components/text-field.tsx 和 src/components/toolbar.tsx 不在 src/app 目录中,因此它们不会被视为页面。它们不会有 URL,也不能成为导航操作的目标。然而,它们可以在 src/app 目录下的页面中作为组件使用。