以下是 Expo Router 的核心用法汇总,涵盖路由配置、导航、参数传递等关键功能(基于 Expo SDK 49+):
路由配置(文件系统路由)
app/
├── (tabs)/ # 嵌套布局组
│ ├── index.js # /tabs/
│ └── [user].js # /tabs/{user}
├── _layout.js # 全局布局
├── index.js # 首页 (/)
├── search/
│ ├── index.js # /search
│ └── [term].js # /search/{term}
└── modal.js # 模态屏 (/modal)
核心导航方法
import { Link, router, useRouter } from 'expo-router';
// 1. 组件导航
<Link href="/profile">前往个人页</Link>
// 2. 编程式导航
router.push('/settings'); // 跳转
router.replace('/login'); // 替换当前路由
router.back(); // 返回
// 3. 获取路由对象
const { push, back, replace } = useRouter();
动态路由参数
文件命名:[param].js 获取参数:
// app/user/[id].js
import { useLocalSearchParams } from 'expo-router';
export default function User() {
const { id } = useLocalSearchParams(); // 获取 /user/123 中的 id
return <Text>用户ID: {id}</Text>;
}
布局系统
全局布局 (app/_layout.js):
export default function Layout() {
return (
<Stack>
<Stack.Screen name="index" options={{ title: '首页' }} />
<Stack.Screen name="profile" options={{ headerShown: false }} />
</Stack>
);
}
嵌套布局:
// app/(tabs)/_layout.js
export default function TabsLayout() {
return (
<Tabs>
<Tabs.Screen name="home" />
<Tabs.Screen name="settings" />
</Tabs>
);
}
路由守卫(认证控制)
// app/_layout.js
import { Redirect } from 'expo-router';
export default function RootLayout() {
const { isAuthenticated } = useAuth();
if (!isAuthenticated) {
return <Redirect href="/login" />;
}
return <Stack />;
}
深层链接配置
- 配置 app.json:
{
"expo": {
"scheme": "myapp",
"plugins": [
["expo-router", { "origin": "https://yourapp.com" }]
]
}
}
- 处理链接:
// app/index.js
import { useUrl } from 'expo-router';
export default function Home() {
const url = useUrl(); // 获取 deep link 参数
// 处理类似 myapp://user/123 的链接
}
高级路由操作
// 1. 传递对象参数
router.push({
pathname: '/user',
params: { id: 123, name: 'Alice' }
});
// 2. 预加载路由
import { usePreload } from 'expo-router';
usePreload('/heavy-screen'); // 提前加载资源
// 3. 监听路由事件
import { useFocusEffect } from 'expo-router';
useFocusEffect(() => {
console.log('屏幕已聚焦');
});
路由类型(TypeScript)
// 定义路由参数类型
export type RootStackParamList = {
index: undefined;
profile: { userId: string };
};
// 在组件中使用
const { userId } = useLocalSearchParams<{ userId: string }>();
注意事项
- 文件约定:
- index.js 代表目录默认路由
- _layout.js 为布局文件
- (group) 目录名用于逻辑分组(不显示在URL)
- 路由行为:
- 所有路由默认使用 栈导航(可配置为 Tabs/Drawer)
- 路径匹配规则:app/**/*.js → /path
- 开发工具:
- npx expo start # 启动开发服务器
Ctrl + R # 查看路由调试面板
官方文档:Expo Router Docs 示例项目:GitHub - expo/router-example
实用代码片段
模态屏实现:
// app/modal.js
export default function Modal() {
return (
<View style={{ flex: 1 }}>
<Text>模态内容</Text>
<Link href="../">关闭</Link> {/* 返回上级 */}
</View>
);
}
强制横屏页面:
// app/game/_layout.js
import * as ScreenOrientation from 'expo-screen-orientation';
export default function GameLayout() {
useLayoutEffect(() => {
ScreenOrientation.lockAsync(
ScreenOrientation.OrientationLock.LANDSCAPE
);
return () => ScreenOrientation.unlockAsync();
}, []);
return <Stack />;
}