。。-- 。。 说起来,这是个伤心的故事,昨天通过文件名的结构来定义路由,深层级路由,找不到页面。
看着Expo文档我陷入了深思,我不应该连个文档都不理解啊。文档就是这么写的啊。。-- 。。
让我一度怀疑我连那个表达的很清晰的官方文档都没看懂。我真是认认真真看了一遍又一遍,没错,真的是反复阅读了Expo 路由部分的文档。
但test/demo/detail…就是不生效,最后我鬼使神差的重新run了一下,结果一下子就好了。。-- 。。
读了那么多遍文档,不写个笔记,感觉亏了。。。-- 。。。【嚎啕大哭】
Expo Router 基于文件系统进行路由配置,通过文件和文件夹的结构来定义路由。
首先来理解一下文件夹的结构:
app/
│ ── test
│ ├── _layout.tsx //应用于当前目录及其子目录中的公共布局
│ ├── details.tsx // '/details' -->对应app/test/details 路由
│ └── index.tsx // '/'-->对应app/test的根目录
├── +html.tsx
├── +not-found.tsx
└── _layout.tsx //应用于整个应用的根布局
文件名的命名规则:
1. Expo router通过文件夹的名字和结构自动生成路由
index.tsx作用
:作为所在目录的默认页面。
路由:对应父级路径或根路径。
details.tsx作用
:定义名为 details的页面组件。
路由:对应 /details 路径。
例如:
app/test/index.tsx
文件夹 matchesapp/test
路由app/test/details.tsx
文件夹 matches/test/details
路由
2. 动态路由:
2.1 group 分组文件
- 语法:用()括号包裹的文件夹
- 作用:不会出现在 URL 路径中,仅用于组织代码结构
app/
│ ── (yy,jj)
│ ├── _layout.tsx //应用于当前目录及其子目录中的公共布局
│ ├── details.tsx // '/details' -->对应app/details 路由
│ └── index.tsx // '/'-->对应app/
├── +html.tsx
├── +not-found.tsx
└── _layout.tsx //应用于整个应用的全局布局
用()括号包裹的文件夹,不会出现在 URL 路径中,仅用于组织代码结构,不影响 URL 路径
app/(yy,jj)/details
navigates to app/details
app/(yy,jj)/index
navigates to app/
2.2. 动态路由
- 语法:[param].tsx
- 作用:匹配动态参数。
app/
│ ── (yy,jj)
│ ├── _layout.tsx //应用于当前目录及其子目录中的公共布局
│ ├── details.tsx // '/details' -->对应app/details 路由
│ ├── [anyName].tsx // '/anyname' -->对应app/任意路由名字的 路由
│ └── index.tsx // '/'-->对应/test的根目录
├── +html.tsx
├── +not-found.tsx
└── _layout.tsx //应用于整个应用的全局布局
app/(yy,jj)/[anyName]
navigates to app/:任何名字的路由名字
2.3. 深层级的路由
app/
│ ── (yy,jj)
│ ├── demo
│ │ ├── details.tsx // 对应app/demo/details 路由
│ │ ├── [anyName].tsx // 对应app/demo/任意路由名字的 路由
│ │ └── index.tsx // '/'-->对应app/demo的根目录
│ ├── _layout.tsx //应用于当前目录及其子目录中的公共布局
│ ├── details.tsx // '/details' -->对应app/details 路由
│ ├── [anyName].tsx // '/anyname' -->对应app/任意路由名字的 路由
│ └── index.tsx // '/'-->对应/test的根目录
├── +html.tsx
├── +not-found.tsx
└── _layout.tsx //应用于整个应用的全局布局
app/(yy,jj)/demo/details
navigates to app/demo/details
app/(yy,jj)/demo/index
navigates to app/demo
app/(yy,jj)/demo/[anyName]
navigates to app/demo/:任何名字的路由名字
app/
│ ── (yy,jj)
│ ├── [demo] //动态文件夹的名字
│ │ ├── details.tsx // 对应app/demo/details 路由
│ │ ├── [anyName].tsx // 对应app/demo/任意路由名字的 路由
│ │ └── index.tsx // '/'-->对应app/demo的根目录
│ ├── _layout.tsx //应用于当前目录及其子目录中的公共布局
│ ├── details.tsx // '/details' -->对应app/details 路由
│ ├── [anyName].tsx // '/anyname' -->对应app/任意路由名字的 路由
│ └── index.tsx // '/'-->对应/test的根目录
├── +html.tsx
├── +not-found.tsx
└── _layout.tsx //应用于整个应用的全局布局
app/(yy,jj)/[demo]/details
navigates to app/:任何名字的路由名字/details
app/(yy,jj)/[demo]/index
navigates to app/:任何名字的路由名字
app/(yy,jj)/[demo]/[anyName]
navigates to app/:任何名字的路由名字/:任何名字的路由名字
✨✨✨动态路由要注意乱输入路由的情况
useEffect(() => {
// 动态路由,胡乱输入触发边界错误
if (!pathIsRight(pathname)) throw new Error('path error');
}, [pathname])
_layout.tsx的作用
_layout.tsx的作用:定义当前目录及其子目录中的公共布局
根目录的 _layout.tsx
:应用于整个应用的根布局。
layout.tsx 中定义了其所在文件夹下的所有导航栏, 供其所在文件夹下的所有Stack.Screen页面访问和使用。
import { Stack } from 'expo-router';
export default function RootLayout() {
return (
<Stack>
{/* 可以在这里配置全局导航选项,如标题、是否显示导航栏*/}
<Stack.Screen
name="index"
options={{
title: 'Home',
}}
/>
</Stack>
);
}
(tabs)/_layout.tsx
:仅应用于 tabs 分组内的页面。
用白话举个例子:
上图中_layout.tsx 定义了(uu) 文件夹及其子文件夹的公共布局。
所以,屏幕导航器 Stack.Screen 中配置路由/pre/(uu)
上图中_layout.tsx 定义了[demo] 文件夹及其子文件夹的公共布局。
所以,屏幕导航器 Stack.Screen 中配置路由/pre/(uu)/[demo]
加号 + 前缀的文件
+filename.tsx:的作用
+filename.tsx的作用:用于定义特殊的全局配置或页面,不对应常规的路由
+html.tsx
:自定义 Web 版本应用的根 HTML 模板。
使用场景:需要修改默认的 HTML 结构,添加自定义元标签或脚本时。+not-found.tsx
:定义全局的404页面。
总结:命名规则
- 括号 () :用于分组,组织代码,不影响路由。
- 下划线 _ :定义布局,应用于当前及子目录。
- 加号 + :特殊文件或路由,全局配置或特殊页面。
- 方括号 [] :动态路由,匹配参数化路径。