文章目录
- 1 react路由
- 1.1 核心库:React Router
- 安装
- 1.2 基本路由配置
- 路由入口组件
- 定义路由
- 1.3 导航方式
- 使用 `<Link>` 组件
- 编程式导航
- 1.4 动态路由参数
- 定义参数
- 获取参数
- 1.5 嵌套路由
- 父路由配置
- 子路由占位符
- 1.6 重定向与404页面
- 重定向
- 404页面
- 1.7 路由守卫(权限控制)
- 1.8 代码分割与懒加载
- 注意事项
- 完整示例
- 2 问卷系统业务流程图
- 阶段1:用户身份验证
- 阶段2:问卷创建与管理
- 阶段3:问卷发布与分发
- 阶段4:数据收集与填写
- 阶段5:数据分析与处理
- 阶段6:问卷终止或循环
- 关键分支说明
- 3 路由设计
- 3.1 页面对应的路由
- 3.2、Layout模版
- 4 实践
- 4.1 创建页面
- 4.2 创建layout
- 4.3 配置router
- 4.4 使用路由api-页面跳转和获取参数
- 4.5 自定义网页标题和favicon
- 结语
1 react路由
1.1 核心库:React Router
React 官方推荐使用 React Router 实现路由功能。当前主流版本是 v6.x(注意与旧版 v5 的语法差异)。
安装
yarn add react-router-dom
1.2 基本路由配置
路由入口组件
在应用顶层包裹 <BrowserRouter>
(或 <HashRouter>
):
import { BrowserRouter } from 'react-router-dom';
function App() {
return (
<BrowserRouter>
{/* 路由配置 */}
</BrowserRouter>
);
}
定义路由
使用 <Routes>
和 <Route>
定义路由映射:
import { Routes, Route } from 'react-router-dom';
import Home from './Home';
import About from './About';
import User from './User';
function App() {
return (
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/user/:id" element={<User />} />
</Routes>
);
}
1.3 导航方式
使用 <Link>
组件
替代 <a>
标签实现无刷新跳转:
import { Link } from 'react-router-dom';
function Nav() {
return (
<nav>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
</nav>
);
}
编程式导航
通过 useNavigate
Hook 跳转:
import { useNavigate } from 'react-router-dom';
function Button() {
const navigate = useNavigate();
return (
<button onClick={() => navigate('/user/123')}>
Go to User 123
</button>
);
}
1.4 动态路由参数
定义参数
在路径中使用 :param
定义动态参数:
<Route path="/user/:id" element={<User />} />
获取参数
通过 useParams
Hook 获取参数:
import { useParams } from 'react-router-dom';
function User() {
const { id } = useParams();
return <div>User ID: {id}</div>;
}
1.5 嵌套路由
父路由配置
使用嵌套 <Route>
定义子路由:
<Route path="/dashboard" element={<Dashboard />}>
<Route path="profile" element={<Profile />} />
<Route path="settings" element={<Settings />} />
</Route>
子路由占位符
父组件中通过 <Outlet>
渲染子路由内容:
import { Outlet } from 'react-router-dom';
function Dashboard() {
return (
<div>
<h1>Dashboard</h1>
<Outlet /> {/* 子路由在此渲染 */}
</div>
);
}
1.6 重定向与404页面
重定向
使用 <Navigate>
组件:
<Route path="/old-path" element={<Navigate to="/new-path" />} />
404页面
通过 path="*"
匹配未知路径:
<Route path="*" element={<NotFound />} />
1.7 路由守卫(权限控制)
通过封装 <Route>
实现登录验证等逻辑:
function PrivateRoute({ children }) {
const isAuthenticated = checkAuth(); // 自定义权限检查
return isAuthenticated ? children : <Navigate to="/login" />;
}
// 使用
<Route path="/admin" element={<PrivateRoute><Admin /></PrivateRoute>} />
1.8 代码分割与懒加载
结合 React.lazy
实现路由懒加载:
const About = React.lazy(() => import('./About'));
<Route path="/about" element={
<React.Suspense fallback={<Loading />}>
<About />
</React.Suspense>
} />
注意事项
- 版本兼容性:v6 与 v5 差异较大(如
Switch
替换为Routes
,component
改为element
)。 - 路径匹配:v6 默认精确匹配,无需添加
exact
属性。 - 相对路径:v6 支持嵌套路由中的相对路径跳转。
完整示例
import { BrowserRouter, Routes, Route, Link } from 'react-router-dom';
function App() {
return (
<BrowserRouter>
<nav>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
</nav>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/user/:id" element={<User />} />
<Route path="*" element={<NotFound />} />
</Routes>
</BrowserRouter>
);
}
掌握这些核心概念后,你可以构建复杂的路由逻辑,实现动态页面切换、权限控制等高级功能。
2 问卷系统业务流程图
阶段1:用户身份验证
阶段2:问卷创建与管理
阶段3:问卷发布与分发
阶段4:数据收集与填写
阶段5:数据分析与处理
阶段6:问卷终止或循环
关键分支说明
- 权限控制
- 管理员可批量管理问卷、审核敏感内容;
- 普通用户仅限操作自有问卷。
- 异常处理
- 填写中断自动保存草稿;
- 提交失败时提示错误类型(如必填项未填)。
- 高级功能扩展
- 付费版支持A/B测试、高级分析;
- 企业版集成SSO登录、数据加密。
此流程图覆盖了问卷系统从创建到分析的核心业务闭环,可根据实际需求调整分支复杂度。
3 路由设计
3.1 页面对应的路由
- 首页:
/
- 登录:
/login
- 注册:
/register
- 问卷管理:
/manage
- 我的问卷:
/manage/list
- 星标问卷:
/manage/star
- 回收站:
/manage/trash
- 我的问卷:
- 问卷详情:
/question
- 编辑问卷:
/question/edit/:id
- 问卷统计:
/question/stat/:id
- 编辑问卷:
- 404:访问不存在页面跳转404
3.2、Layout模版
Axure RP设计布局
Layout:布局,用于设置应用整体结构。
-
MainLayout:整体布局
-
头部
- 网站标题、log
- 首页导航
- 登录/注册、个人中心等
-
主体
- 左侧导航菜单
- 右侧内容
-
底部:
- 网站信息:备案、联系方式等
-
-
ManageLayout
-
QuestionLayout
4 实践
-
按设计,新建若干页面
-
为每个页面配置路由
-
分配对应的Layout模版
4.1 创建页面
- pages
- manage:问卷管理
- List.tsx:我的问卷
- List.module.scss:我的问卷样式
- Star.tsx:标星问卷
- Trash.tsx:回收站
- question:问卷详情
- Edit
- index.tsx:编辑问卷
- Stat
- index.tsx:问卷统计
- Edit
- Home.tsx:默认页
- Login.tsx:登录页
- NotFound.tsx:404跳转页
- Register.tsx:注册页
- manage:问卷管理
4.2 创建layout
- layouts
- MainLayout.tsx:主布局
- ManageLayout.module.scss:主布局样式
- ManageLayout.tsx:问卷管理布局
- QuestionLayout.tsx:问卷详情布局
4.3 配置router
- route
- index.tsx
代码如下所示:
import { createBrowserRouter } from "react-router-dom";
import MainLayout from "../layouts/MainLayout";
import ManageLayout from "../layouts/ManageLayout";
import QuestionLayout from "../layouts/QuestionLayout";
import Home from "../pages/Home";
import Login from "../pages/Login";
import Register from "../pages/Register";
import NotFound from "../pages/NotFound";
import List from "../pages/manage/List";
import Star from "../pages/manage/Star";
import Trash from "../pages/manage/Trash";
import Edit from "../pages/question/Edit";
import Stat from "../pages/question/Stat";
const router = createBrowserRouter([
{
path: "/",
element: <MainLayout />,
children: [
{
path: "/",
element: <Home />,
},
{
path: "login",
element: <Login />,
},
{
path: "register",
element: <Register />,
},
{
path: "manage",
element: <ManageLayout />,
children: [
{
path: "list",
element: <List />,
},
{
path: "star",
element: <Star />,
},
{
path: "trash",
element: <Trash />,
},
],
},
{
path: "*",
element: <NotFound />,
},
],
},
{
path: "/question",
element: <QuestionLayout />,
children: [
{
path: "edit/:id",
element: <Edit />,
},
{
path: "stat/:id",
element: <Stat />,
},
],
},
]);
export default router;
4.4 使用路由api-页面跳转和获取参数
页面跳转
- useNavigate
- Link
Home.tsx代码如下所示:
import { FC } from "react";
import { useNavigate, Link } from "react-router-dom";
const Home: FC = () => {
const nav = useNavigate();
function clickHandler() {
nav({
pathname: "/login",
search: "a=20",
});
}
return (
<div>
<p>Home</p>
<div>
<button onClick={clickHandler}>登录</button>
<Link to="/register">注册</Link>
</div>
</div>
);
};
export default Home;
传参和获取参数
传参参考上面示例,获取参数
- useParams
- useSearchParams
import { FC } from "react";
import { useParams } from "react-router-dom";
const Edit: FC = () => {
const { id = "" } = useParams();
return <div>Edit {id}</div>;
};
export default Edit;
import { FC } from "react";
import { useSearchParams } from "react-router-dom";
import { useImmer } from "use-immer";
import QuestionCard from "../../components/QuestionCard";
import styles from "./List.module.scss";
...
const List: FC = () => {
const [searchParams] = useSearchParams();
console.log("keyword", searchParams.get("keyword"));
...
};
export default List;
4.5 自定义网页标题和favicon
修改首页index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>问卷调查</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
使用第三方ahooks
...
import { useTitle } from "ahooks";
...
const List: FC = () => {
useTitle('调查问卷-我的问卷')
...
};
export default List;
结语
❓QQ:806797785
⭐️仓库地址:https://gitee.com/gaogzhen
⭐️仓库地址:https://github.com/gaogzhen