路由迁移
Vue Router → React Router v5 完整对照
快速对照表
Vue Router 核心 API → React Router v5
| Vue Router | React Router v5 | 说明 |
|---|---|---|
<router-view> |
<Route component={...}> |
路由出口 |
<router-link> |
<Link> / <NavLink> |
声明式导航 |
$route.params |
useParams() |
路由参数 |
$route.query |
useSearchParams() |
查询参数 |
$router.push() |
useHistory().push() |
编程式导航 |
beforeEach |
<Route render> 或自定义 Hook |
路由守卫 |
| 嵌套路由 | 嵌套 <Route> |
子路由配置 |
路由配置
Vue Router 配置 vs React Router 配置
// router/index.ts
import VueRouter from 'vue-router'
const routes = [
{
path: '/',
component: Home
},
{
path: '/user/:id',
component: UserLayout,
children: [
{ path: '', component: UserProfile },
{ path: 'posts', component: UserPosts }
]
}
]
const router = new VueRouter({
mode: 'history',
routes
})
// App.tsx
import {
BrowserRouter,
Route,
Switch
} from 'react-router-dom'
const App: React.FC = () => (
<BrowserRouter>
<Switch>
<Route
exact
path="/"
component={Home}
/>
<Route
path="/user/:id"
component={UserLayout}
/>
</Switch>
</BrowserRouter>
)
// UserLayout.tsx - 嵌套路由
const UserLayout: React.FC = () => {
const { id } = useParams<{ id: string }>()
return (
<div>
<h1>User {id}</h1>
<Route
exact
path="/user/:id"
component={UserProfile}
/>
<Route
path="/user/:id/posts"
component={UserPosts}
/>
</div>
)
}
路由参数
获取路由参数和查询参数
<template>
<div>
<p>用户ID: {{ $route.params.id }}</p>
<p>搜索: {{ $route.query.keyword }}</p>
</div>
</template>
<script>
export default {
computed: {
userId() {
return this.$route.params.id
},
keyword() {
return this.$route.query.keyword
}
}
}
</script>
import { useParams, useSearchParams } from 'react-router-dom'
const UserPage: React.FC = () => {
// 获取路由参数
const { id } = useParams<{ id: string }>()
// 获取查询参数
const [searchParams] = useSearchParams()
const keyword = searchParams.get('keyword')
return (
<div>
<p>用户ID: {id}</p>
<p>搜索: {keyword}</p>
</div>
)
}
路由守卫
Vue Router beforeEach → React 自定义 Hook
// router/index.ts
router.beforeEach((to, from, next) => {
const isAuthenticated = !!localStorage.getItem('token')
if (to.meta.requiresAuth && !isAuthenticated) {
// 未登录,跳转到登录页
next('/login')
} else {
// 允许访问
next()
}
})
// hooks/useAuth.ts
import { useEffect } from 'react'
import { useHistory } from 'react-router-dom'
export function useAuth(requireAuth = true) {
const history = useHistory()
const isAuthenticated = !!localStorage.getItem('token')
useEffect(() => {
if (requireAuth && !isAuthenticated) {
history.replace('/login')
}
}, [requireAuth, isAuthenticated, history])
return { isAuthenticated }
}
// 在需要认证的页面使用
const Dashboard: React.FC = () => {
const { isAuthenticated } = useAuth()
if (!isAuthenticated) {
return null // 或加载中
}
return <div>仪表盘</div>
}