当前位置: 首页 > news >正文

react-问卷星项目(5)

实战

路由

  • 路由设计,网址和页面的关系,就是从业务上分析需要哪些页面哪些页面内容可以抽离,业务流程要有入有出
  • 增加页面和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 <p>Star</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></div><div className={styled.right}>搜索</div></div><div className={styled.content}>{questionList.map((q) => {const { _id } = q;return <QuestionCard key={_id} {...q} />;})}</div><div 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: FC<PropsType> = (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></div><div className={styled.right}>{isPublished ? (<span style={{ color: "green" }}>已发布</span>) : (<span>未发布</span>)}&nbsp;<span>答卷:{answerCount}</span>&nbsp;<span>{createAt}</span></div></div><div className={styled["button-container"]}><div className={styled.left}><button>编辑问卷</button><button>数据统计</button></div><div className={styled.right}><button>标星</button><button>复制</button><button>删除</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 (<div><div>MainLayout header</div><div><Outlet /></div><div>MainLayout 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}><p>MainLayout left</p><button>创建问卷</button><br /><a href="#">我的问卷</a><br /><a href="#">星标问卷</a><br /><a href="#">回收站</a><br /></div><div 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 (<div><div>QuestionLayout header</div><div><Outlet /></div><div>QuestionLayout 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: "b=21", // 路径附加参数,类似get});}return (<div><p>Home</p><div><button onClick={clickHandler}>登录</button><Link 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 (<div><p>Login</p><div>{/* -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 <p>Edit{id}</p>;
};
export default Edit;

question目录下的文件比较特别,需要跳转的时候传参,进行完上面的设置后可以在路径后面加入参数测试是否成功,如图所示

http://www.lryc.cn/news/452773.html

相关文章:

  • 08.useInterval
  • 【Android 源码分析】Activity生命周期之onDestroy
  • 增强现实中的物体识别与跟踪
  • 移动端实现下拉刷新和上拉加载(内含案例)
  • Opencv第十一章——视频处理
  • Flutter 3.24 AAPT: error: resource android:attr/lStar not found.
  • C++——输入一个2*3的矩阵, 将这个矩阵向左旋转90度后输出。(要求:使用指针完成。)
  • AI芯片WT2605C赋能厨房家电,在线对话操控,引领智能烹饪新体验:尽享高效便捷生活
  • 详解调用钉钉AI助理消息API发送钉钉消息卡片给指定单聊用户
  • 57 长短期记忆网络(LSTM)_by《李沐:动手学深度学习v2》pytorch版
  • Linux系统安装教程
  • Redis: Sentinel工作原理和故障迁移流程
  • 通信工程学习:什么是IGMP因特网组管理协议
  • 高效批量导入多个SQL文件至SQL Server数据库的实用方法
  • 【树莓派系列】树莓派wiringPi库详解,官方外设开发
  • 前端模块化CommonJs、ESM、AMD总结
  • JavaWeb - 8 - 请求响应 分层解耦
  • 1G,2G,3G,4G,5G各代通信技术的关键技术,联系和区别
  • 【宽搜】2. leetcode 102 二叉树的层序遍历
  • Go语言实现长连接并发框架 - 请求分发器
  • Redis: 集群测试和集群原理
  • 问题解决实录 | bash 中 tmux 颜色显示不全
  • 古典舞在线交流平台:SpringBoot设计与实现详解
  • 五子棋双人对战项目(6)——对战模块(解读代码)
  • 查缺补漏----I/O中断处理过程
  • Java API接口开发规范
  • Go语言实现长连接并发框架 - 任务管理器
  • 【大数据】深入解析分布式数据库:架构、技术与未来
  • uniapp框架中实现文件选择上传组件,可以选择图片、视频等任意文件并上传到当前绑定的服务空间
  • GEE教程:NASA/GRACE/MASS_GRIDS/LAND数据的查看不同时期液态水数据的变化情况