《IT猿题库》项目实战
预习资料
项目地址:http://codesohigh.com/yuantiku
参考该项目及这份笔记,并尝试搭建项目。
实战课学习目标
结合React、React Redux、React Router、Hooks、Axios与material-ui,完成《IT猿题库》项目。
一、项目参考
项目地址:http://codesohigh.com/yuantiku
界面效果:
项目图片资源
链接: https://pan.baidu.com/s/1kTOSazkZ0i9MKnjLhQmiKQ 提取码: 9p5h
二、技术栈
1、React
简介:使用React开发移动端项目
官网地址:https://react.docschina.org/
2、Material-UI
简介:一个基于 Preact / React / React Native 的 UI 组件库
三、项目创建与安装
1、依赖安装
使用 npx create-react-app yuantiku 创建完项目后,安装material-ui:
2、FastClick解决
在 public/index.html 的 head 标签中插入:
这里建议把 https://as.alipayobjects.com/g/component/fastclick/1.0.6/fastclick.js 和 https://as.alipayobjects.com/g/component/es6-promise/3.2.2/es6-promise.min.js 保存到本地
3、调用
在 App.js 中:
然后就可以看到按钮被正式引入:
4、清除默认边距与样式
npm包路径:https://www.npmjs.com/package/reset-css
安装:
使用:
四、蓝湖
将设计图用photoshop打开,并上传至蓝湖。此时的设计图是3x尺寸,因此要勾选对应的1125px尺寸。
五、配置rem
1、安装依赖包
2、解包
解包需要先做git提交,否则无法解包,因此先执行:
接下来直接解包:
3、配置loader
解包后,可以看到项目目录下多了一个 config 文件夹。打开 config/webpack.config.js :
搜索 postcss-loader ,添加:
这里的 rootValue: 112.5 的意思就是1rem = 112.5px 这个是根据1125px设计稿来的。
4、flexible引入
在 入口文件 index.js 里引入 lib-flexible:
5、rem测试
在 App.js 中写个类名,创建 App.css ,并写入:
接下来打开浏览器:
可以看到,iphoneX的尺寸下,html的字体大小为37.5px,此时box的宽度为10rem,再来看看其他尺寸:
当其他尺寸下时,可以发现html字体大小为41.1px,而此时box的宽度仍为10rem,这就代表我们rem配置成功了。
6、兼容ipad
但是,当你点开ipad时,会发现盒子兼容出了问题,这是因为淘宝弹性布局方案lib-flexible不兼容ipad和ipad pro。我们这里给出解决方案:
在public>index.html的head标签中添加:
这样,我们就解决ipad的兼容问题了。
7、修改meta标签
六、配置less
1、安装
2、解包
接下来要解包,如果上一步你已经解包过,就直接跳过。
如果未解包,请以上参考第五步。
3、配置loader
找到 webpack.config.js ,搜索 sassRegex:
搜索 sass-loader 后,在其下方添加:
修改了配置文件,记得重新 yarn start 哦!
4、测试less
将 App.css 改为 App.less 进行测试,依然没问题。
5、文字三属性
在 App.less 中添加:
这里注意,由于html和body标签已被强行设定了font-size,因此我们设定#root的font-size即可。
七、登录判断
如果我们每个页面都需要在 componentWillMount 判断是否已经登录,那么太麻烦。React中有mixins,但已经被淘汰了。取而代之,我们使用高阶函数来操作。
在src下创建 hoc>index.js :
在任何一个页面都可以如下调用(这里以Home页面举例):
八、request封装
1、接口文档
IT猿题库【IT猿题库】 http://www.docway.net/project/1eRv5Lh2UW9/share/1evckeXPiQy 阅读密码:zhaowenxian
2、封装request
react的数据请求我们依然使用axios,我们先封装request:
Token过期:
如果后端判断到token过期,可以在响应拦截器到reject之前:
3、解决跨域
方案一:
react简单解决跨域可以直接在 package.json 中添加 proxy 属性
方案二:
如果你已经进行了 npm run eject ,建议你直接修改 config>webpackDevServer.config.js :
方案三(推荐):
安装 http-proxy-middleware :
这里注意,http-proxy-middleware 模块是有版本区别的,默认安装最新版本,然后在 src 目录下新建 setupProxy.js :
重新 npm run start 即可解决跨域。
4、api导出
我们做请求时的api需要导出:
5、请求
九、路由配置
1、安装
安装 react-router-dom:
2、路由配置
src 下创建 router/index.js:
App.js 中:
而 src/index.js 下:
可以看到:
3、创建五个页面
src下创建 views/Home.jsx + Fast.jsx + User.jsx + Login.jsx + Register.jsx + Error.jsx,分别代表:首页+快速刷题+我的+登录页+404页面,并在router下做配置:
修改 App.js :
如此,当我们在浏览器输入 http://localhost:3000 时,就会帮我们自动跳到 http://localhost:3000/home ,如果随意输入 http://localhost:3000/aaa ,就会自动重定向到错误页面。
十、Tabbar配置
这里参照 material-ui 的 Bottom Navigation 底部导航栏 :https://material-ui.com/zh/components/bottom-navigation/ 。
1、Tabbar引用
src下创建 components/Tabbar.js :
src/components/less/Tabbar.less:
src/components/HomeTab.js、src/components/FastTab.js 及 src/components/UserTab.js :
2、函数式组件路由
在 Tabbar.js 中,使用hooks:
如此,就实现了路由切换。
3、Tabbar动态化
4、最终Tabbar代码
十一、Toast组件
1、Toast组件封装
这里需要结合react-redux来实现。首先新建 Toast.jsx:
Toast.less 中:
在 store/reducer.js 中:
使用时机:
比如:每个接口的请求若报500并返回1002,就代表token错误或过期,此时就需要判断token,如果没有token,就直接跳到登录页,跳过去之前,就要先显示loading效果
在 App.jsx 中引入Toast组件:
2、调用方式
十三、登录注册页套用
⚠️ 这里插播一句:登录注册页请直接套用代码就好!
效果如下:
1、登录页代码
将示例代码直接复制粘贴,然后稍做修改:
然后在 request/api.js 中:
如果缺少什么依赖,就按照提示安装即可。这里主要还缺少:
2、注册页代码
然后在 request/api.js 中:
十三、开发小提示
1、JSX条件判断
在react的class组件中如何使用 switch...case 语法?
使用一个自执行函数,在函数体内使用 switch...case 。
2、路由跳转问题
当我们使用
得到 push of undefined 的报错时,可以这么解决:
如果使用的是函数式组件,还可以借助hook:
3、自定义进度条
4、配置项目@指向src
在保证解包 yarn eject 之后,找到 webpack.config.js ,搜索 alias 对象,可以得到3个结果,索引第2个结果,并配置:
重跑项目即可使用@符号指向src。
5、组件中无法使用history?
页面在Router中配置了,但它下面的组件无法使用 this.props.history.push() 进行跳转,并且报了如下错误:
这是因为组件并没有使用 history 的能力,可以使用以上的提示2,也可以将配置过路由的父级的history传递给该组件:
6、setState是异步的
以下这段代码:
为什么以上打印出来是1,而不是2呢?
因为setState是异步的,如果想要正常打印出2,需要:
也就是,setState有第二个参数,属于回调函数。
7、统一使用消息提示
在使用消息提示的时候,我们每次都要单独写样式比较麻烦,这里提供代码,当你要使用 material-ui 的alert组件时,可以这样引入:
记得先在公用的 base.less 中写入:
这里注意:
severity属性规定了消息提示框的类型,分别有:
error - 错误提示(红色)
warning - 警告提示(橙色)
info - 信息提示(蓝色)
success - 成功提示(绿色 - 默认值)
至于消息提示框的显示隐藏,可以通过:
来控制。记住,是 display: flex 不是 display: block 。
Alert引用代码演示:
8、ReactRedux包装Alert
安装 redux 与 react-redux:
将统一消息提示封装到组件 Alert.js 中:
src目录下创建 store/reducer.js :
创建 store/index.js :
src/App.js 中引入 Alert 组件:
最后在 <App /> 外套用提供器Provider:
后面某个页面想要触发 Alert ,就可以在该页面使用连接器如下:
9、React插入html
使用 dangerouslySetInnerHTML 属性。
这里注意:html前面是两个下划线。
10、反序列化问题
在子组件中获取到的props,想要将props中的字符串转对象或数组,需要使用 JSON.parse(this.props.content || "[]") 。但接收props存在请求异步的延迟,因此会报错:
因此,我们可以改写为:
11、React实现移动端滑动
先给元素加上css定位:
js实现:
12、答题之多选组件UI部分代码
多选组件比单选组件复杂,需要给数组项中手动添加ifSelect=false。
13、事件参数与事件对象
当我们这么写事件时,存在一个问题,事件对象的位置不知道是在index之前还是index之后,如:
14、禁用Link
想要禁用Link,开发阶段使用 BrowserRouter 可以使用:
但如果上线使用 HashRouter ,就会跳到404页面,因此需要补充:
十四、项目打包
1、Hash模式打包
打包需要首先向 package.json 中添加:
然后找到 router/index.js :
打包完成后,凡是使用了 this.props.location.state.xxx 传值的路由,都会碰上 Cannot read property 'xxx' of undefined 的报错。
原因是HashRouter模式不支持 this.props.location.state 获取数据,需要使用: this.props.location.params 。因此在路由传值的写法上,也要改为这种形式:
打包后可能会发现 history.goBack() 会造成上一级路由参数丢失,此时可以尝试 history.go(-1)。
2、History模式打包
在 package.json 中:
找到 router/index.js:
但这里必须要有nginx的配置。
首先 ssh root@IP地址 连接上服务器,然后执行 whereis nginx,然后使用vim修改nginx.conf:
修改完配置后,浏览器打开 http://www.abcd.com/yuantiku 即可。
3、跨域
生产环境下跨域需要nginx配合解决,如果你已在开发环境下使用 /api 代理 https://www.ahsj.link/ramb,那么nginx的配置为:
十五、作业
作业1(初级)
使用Class Component完成微博发布功能。
作业2(中级)
使用Function Component完成微博发布功能。
作业3(高级)
使用Class Component完成Todolist。
作业4(顶级)
使用Function Component完成Todolist。
最后更新于
这有帮助吗?







