📋 快速对照表

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>
}
← dva 数据流 Webpack 4 →