企业微信网站开发公司,国内优秀html网站,甘肃温室大棚建设网站,wordpress 快速建站实战
路由
路由设计#xff0c;网址和页面的关系#xff0c;就是从业务上分析需要哪些页面哪些页面内容可以抽离#xff0c;业务流程要有入有出增加页面和Layout模版#xff0c;模版就是抽离页面公共部分#xff0c;比如都有顶部或者左侧导航#xff0c;直接上代码网址和页面的关系就是从业务上分析需要哪些页面哪些页面内容可以抽离业务流程要有入有出增加页面和Layout模版模版就是抽离页面公共部分比如都有顶部或者左侧导航直接上代码就是组件复用的思想使用React-router增加路由配置目前路由模块只有这一个工具 React-router
路由工具
其中Outlet和vue中的slot插槽相似通过下载路由并导入获得 下载React-router npm install react-router-dom --save 这一篇实战性比较强直接上代码相关部分在代码中都有注释
项目的目录结构如下components是存放组件Layouts存放布局布局就是页面抽离出的公共部分比如几个几个页面都有顶部和底部这两个就可以抽出来成布局pages存放页面在React中都是组件但是在业务上我们称之为页面结构就是右边这个图所示有点模糊凑合着看从老师的视频里截出来的 全部先新建出来后按照下面的格式先布局就可以。
// 星标问卷页面
import React, { FC } from react;
const Star: FC () {return pStar/p;
};
export default Star;
接下来一个个页面开始细化基本思路就是先list文件挂载到app中然后添加问卷列表卡片组件Question再然后完善布局其中布局有些注意点就是一部分是固定的但是还有一部分是可以切换的可以切换的这一块需要用的路由的一个类下面碰到的时候会注释。
ps:新项目记得把sass之类的下载好忘记指令的可以看这篇反正什么报错下载什么就可以
List.tsx
import React, { FC, useState } from react;
import { useSearchParams } from react-router-dom;
import QuestionCard from ../../components/QuestionCard;
import styled from ./List.module.scss;const rawQuestionList [{_id: q1,title: 问卷1,isPublished: true,isStar: false,answerCount: 5,createAt: 3月10日 13:23,},{_id: q2,title: 问卷2,isPublished: false,isStar: true,answerCount: 15,createAt: 3月22日 13:23,},{_id: q3,title: 问卷3,isPublished: true,isStar: true,answerCount: 100,createAt: 4月10日 13:23,},{_id: q4,title: 问卷4,isPublished: false,isStar: false,answerCount: 98,createAt: 3月23日 13:23,},
];const List: FC () {const [searchParams] useSearchParams();console.log(keyword, searchParams.get(keyword));const [questionList, setQuestionList] useState(rawQuestionList);return (div className{styled.header}div className{styled.left}h3我的问卷/h3/divdiv className{styled.right}搜索/div/divdiv className{styled.content}{questionList.map((q) {const { _id } q;return QuestionCard key{_id} {...q} /;})}/divdiv className{styled.footer}footer/div/);
};export default List;
List.module.scss
.header{display: flex;.left{flex: 1;}.right{flex: 1;text-align: right;}
}.content{margin-bottom: 20px;
}.footer{text-align: center;
}body{background-color: #f1f1f1;
}
QuestionCard.tsx
import React, { FC, useEffect } from react;
// import ./QuestionCard.css;
import styled from ./QuestionCard.module.scss;
import classnames from classnames;
type PropsType {_id: string;title: string;isPublished: boolean;isStar: boolean;answerCount: number;createAt: string;// 问号是可写可不写跟flutter语法相似deletQuestion?: (id: string) void;pubQuestion?: (id: string) void;
};const QuestionCard: FCPropsType (props: PropsType) {const { _id, title, createAt, answerCount, isPublished } props;return (div className{styled.container}div className{styled.title}div className{styled.left}a href#{title}/a/divdiv className{styled.right}{isPublished ? (span style{{ color: green }}已发布/span) : (span未发布/span)}nbsp;span答卷{answerCount}/spannbsp;span{createAt}/span/div/divdiv className{styled[button-container]}div className{styled.left}button编辑问卷/buttonbutton数据统计/button/divdiv className{styled.right}button标星/buttonbutton复制/buttonbutton删除/button/div/div/div);
};export default QuestionCard;
QuestionCard.module.scss
.container{margin-bottom: 20px;padding: 12px;border-radius: 3px;background-color: white;:hover{box-shadow: 0 4px 10px lightgray;}
}.title{display: flex;.left{flex: 1;}.right{flex: 1;text-align: right;}
}.button-container{display: flex;.left{flex: 1;}.right{flex: 1;text-align: right;button{color: #999;}}
}
下面开始就是布局文件其中用到的Outlet和vue中的插槽比较相似作用就是占位可以实现切换组件的效果
MainLayout.tsx
import React, { FC } from react;
import { Outlet } from react-router-dom;
const MainLayout: FC () {return (divdivMainLayout header/divdivOutlet //divdivMainLayout footer/div/div);
};
export default MainLayout;
ManagerLayout.tsx
import React, { FC } from react;
import { Outlet } from react-router-dom;
import styled from ./MangerLayout.module.scss;
const MangerLayout: FC () {return (div className{styled.container}div className{styled.left}pMainLayout left/pbutton创建问卷/buttonbr /a href#我的问卷/abr /a href#星标问卷/abr /a href#回收站/abr //divdiv className{styled.right}Outlet //div/div);
};
export default MangerLayout;
MangerLayout.module.scss
.container{display: flex;padding: 24px 0;width: 1200px;margin: 0 auto; // 水平居中.left{width: 120px;background-color: aqua;}.right{flex: 1;margin-left: 60px;background-color: aquamarine;}}
QuestionLayout.tsx
import React, { FC } from react;
import { Outlet } from react-router-dom;const QuestionLayout: FC () {return (divdivQuestionLayout header/divdivOutlet //divdivQuestionLayout footer/div/div);
};
export default QuestionLayout;
接下来是路由器编辑
router/index.tsx
// 路由配置
import React from react;
import { createBrowserRouter } from react-router-dom;
import MainLayout from ../Layouts/MainLayout;
import ManagerLayout from ../Layouts/ManagerLayout;
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/manager/List;
import Trash from ../pages/manager/Trash;
import Star from ../pages/manager/Star;
import Edit from ../pages/manager/question/Edit;
import Static from ../pages/manager/question/Static;// 数组表示可以创建多路径
const router createBrowserRouter([{path: /,// 访问根目录时element指向MainLayoutelement: MainLayout /,children: [{path: /,element: Home /,},{path: login,element: Login /,},{path: register,element: Register /,},{path: manager,element: ManagerLayout /,children: [{path: list,element: List /,},{path: star,element: Star /,},{path: trash,element: Trash /,},],},{// 以上页面都没有命中path: *,element: NotFound /,},{path: question,element: QuestionLayout /,children: [{path: edit,element: Edit /,},{path: static,element: Static /,},],},],},{path: question,element: QuestionLayout /,children: [{path: edit/:id,element: Edit /,},{path: static/:id,element: Static /,},],},
]);
export default router;
最后挂载到App上就可以
App.tsx
import { RouterProvider } from react-router-dom;
import router from ./router;function App() {return RouterProvider router{router}/RouterProvider;
}export default App;
可以在路径上添加相应后缀尝试是否能正确切换接下来就是传值和接收值的测试包括使用路由进行页面跳转
Home.tsx
// 首页
import React, { FC } from react;
import { useNavigate, Link } from react-router-dom;const Home: FC () {const nav useNavigate();function clickHandler() {nav({pathname: /login, // 路径search: b21, // 路径附加参数类似get});}return (divpHome/pdivbutton onClick{clickHandler}登录/buttonLink to/register注册/Link/div/div);
};
export default Home;
Login.tsx
// 登陆页面
import React, { FC } from react;
import { useNavigate } from react-router-dom;const Login: FC () {const nav useNavigate();return (divpLogin/pdiv{/* -1就是返回上一个 */}button onClick{() nav(-1)}返回/button/div/div);
};
export default Login;
Edit/index.tsx
// 编辑页面页面比较复杂所以不放在单个页面而是文件夹中
import React, { FC } from react;
import { useParams } from react-router-dom;const Edit: FC () {// 默认值不传入就是空字符串const { id } useParams();return pEdit{id}/p;
};
export default Edit;
question目录下的文件比较特别需要跳转的时候传参进行完上面的设置后可以在路径后面加入参数测试是否成功如图所示