编程式导航
2025年11月29日
作者:管理员
示例代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>React Router 编程式导航</title>
<!-- 引入 Tailwind CSS 进行快速样式设计 -->
<script src="https://cdn.tailwindcss.com/3.4.17"></script>
<!-- 1. React 和 ReactDOM (Production 版本) -->
<script crossorigin src="https://unpkg.com/react@18.3.1/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18.3.1/umd/react-dom.production.min.js"></script>
<!-- 2. React Router 依赖链 (顺序非常重要,Production 版本) -->
<!-- 2.1 @remix-run/router: React Router 6.4+ 的底层路由逻辑 -->
<script src="https://unpkg.com/@remix-run/router@1.15.3/dist/router.umd.min.js"></script>
<!-- 2.2 react-router: 核心 React 绑定 -->
<script src="https://unpkg.com/react-router@6.22.3/dist/umd/react-router.production.min.js"></script>
<!-- 2.3 react-router-dom: DOM 绑定 (我们需要使用的对象在这里) -->
<script src="https://unpkg.com/react-router-dom@6.22.3/dist/umd/react-router-dom.production.min.js"></script>
<!-- Babel 用于解析 JSX -->
<script src="https://unpkg.com/@babel/standalone@7.28.5/babel.min.js"></script>
<style>
.page-enter {
animation: fade-in 0.3s ease-out;
}
@keyframes fade-in {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
</style>
</head>
<body class="bg-gray-50 text-gray-800 min-h-screen">
<div id="root"></div>
<script type="text/babel">
const { HashRouter, Routes, Route, Link, useNavigate } = window.ReactRouterDOM;
function Login() {
const navigate = useNavigate();
const [isLoggedIn, setIsLoggedIn] = React.useState(false);
const handleLogin = () => {
setIsLoggedIn(true);
// 使用 navigate 进行编程式导航
setTimeout(() => {
navigate('/dashboard');
}, 500);
};
return (
<div className="page-enter bg-white p-8 rounded-lg shadow-sm border border-gray-100 max-w-md mx-auto mt-20">
<h1 className="text-3xl font-bold text-gray-900 mb-6">🔐 登录页面</h1>
{isLoggedIn ? (
<div className="text-center">
<p className="text-green-600 mb-4">✓ 登录成功!正在跳转...</p>
<div className="inline-block animate-spin rounded-full h-6 w-6 border-b-2 border-blue-600"></div>
</div>
) : (
<div>
<p className="text-gray-600 mb-6">点击下面的按钮登录,然后会自动跳转到仪表盘</p>
<button
onClick={handleLogin}
className="w-full px-6 py-3 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors font-medium shadow-md hover:shadow-lg">
登录
</button>
<div className="mt-6 p-4 bg-blue-50 text-blue-700 rounded-md border border-blue-100 text-sm">
使用 <code className="bg-blue-100 px-2 py-1 rounded">useNavigate()</code> Hook 进行编程式导航
</div>
</div>
)}
</div>
);
}
function Dashboard() {
const navigate = useNavigate();
const handleLogout = () => {
navigate('/');
};
return (
<div className="page-enter bg-white p-8 rounded-lg shadow-sm border border-gray-100 max-w-2xl mx-auto mt-20">
<h1 className="text-3xl font-bold text-gray-900 mb-6">📊 仪表盘</h1>
<p className="text-gray-600 mb-6">
欢迎来到仪表盘!你已经通过编程式导航成功跳转到这里。
</p>
<div className="space-y-4">
<div className="p-4 bg-green-50 text-green-700 rounded-md border border-green-100">
✓ 登录状态:已登录
</div>
<div className="p-4 bg-blue-50 text-blue-700 rounded-md border border-blue-100">
ℹ️ 这是通过 <code className="bg-blue-100 px-2 py-1 rounded">navigate('/dashboard')</code> 跳转过来的
</div>
</div>
<button
onClick={handleLogout}
className="mt-6 px-6 py-3 bg-red-600 text-white rounded-md hover:bg-red-700 transition-colors font-medium shadow-md hover:shadow-lg">
退出登录
</button>
</div>
);
}
function App() {
return (
<HashRouter>
<div className="min-h-screen">
<Routes>
<Route path="/" element={<Login />} />
<Route path="/dashboard" element={<Dashboard />} />
</Routes>
</div>
</HashRouter>
);
}
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);
</script>
</body>
</html>