0-1、生成唯一id
使用UUID/nanoid(推荐)-----------------npm i nanoid
0-2解构赋值-新
//获取value
const { keyWordElement: {value}} = this;
0-3 js注释在vs code中折叠
//#region
....
//#endregion
1、样式的模块化-解决css冲突
- css文件命名: index.module.css
- 引入: import hello from ‘./index.module.css’;
- 使用:
sad
2、react脚手架
名称
create-react-app
架构
react+webpack+es6+eslint
特点
模块化、组件化、工程化
安装
- 全局安装
- npm i -g create-react-app
创建
create-rect-app 工程名称
文件夹分析
public ---- 静态资源文件夹
- favicon.icon ------ 网站页签图标
- index.html主页面
- logo192.png ------- logo图
- logo512.png ------- logo图
- manifest.json ----- 应用加壳的配置文件
- robots.txt -------- 爬虫协议文件
src ---- 源码文件夹
- App.css -------- App组件的样式
- App.js---------App组件
- App.test.js ---- 用于给App做测试
- index.css ------ 样式
- index.js------入口文件
- React.StructMode---------检查子组件是否有不合理的地方
- logo.svg ------- logo图
- reportWebVitals.js— 页面性能分析文件(需要web-vitals库的支持)
- setupTests.js---- 组件单元测试的文件(需要jest-dom库的支持)
3、react插件使用
- rcc—react class component
- rfc— react function component
4、组件化编程流程
- 1、拆分组件,拆分页面,抽取组件
- 2、实现静态组件,使用组件实现静态页面效果
- 3、实现动态组件
- 1、动态显示初始化数据
- 数据类型
- 数据名称
- 保存在哪个组件
- 2、交互(从绑定事件监听开始)
- 1、动态显示初始化数据
5、父子之间通信
1、父 -> 子
- props
2、子 -> 父
-
父给子传递一个回调函数,当子要给父传递信息时,调用该回调函数
//父 add = (data) => {}; render() { return ( <Child add={this.add} /> ); }; //子 add = () => { this.props.add(data); };
3、兄弟通信
-
消息订阅-发布机制
-
使用PubSub.js-----------------npm i pubsub-js
-
发布消息-数据发送方
PubSub.publish('test', {数据});
-
订阅消息-数据接收方
componentDidMount() { token = PubSub.subscribe('test', (msg, data) => {}); }
-
取消订阅---------组件卸载时将订阅删除
componentwillUnMount() { PubSub.unsubscribe(token); };
-
6、React Ajax
跨域问题
方法1
在package.json中追加如下配置,用于转发
"proxy":"http://localhost:5000"
说明:
- 优点:配置简单,前端请求资源时可以不加任何前缀。
- 缺点:不能配置多个代理。
- 工作方式:上述方式配置代理,当请求了3000不存在的资源时,那么该请求会转发给5000 (优先匹配前端资源)
方法2
编写setupProxy.js配置具体代理规则:
const proxy = require('http-proxy-middleware')
module.exports = function(app) {
app.use(
proxy('/api1', { //api1是需要转发的请求(所有带有/api1前缀的请求都会转发给5000)
target: 'http://localhost:5000', //配置转发目标地址(能返回数据的服务器地址)
changeOrigin: true, //控制服务器接收到的请求头中host字段的值
/*
changeOrigin设置为true时,服务器收到的请求头中的host为:localhost:5000
changeOrigin设置为false时,服务器收到的请求头中的host为:localhost:3000
changeOrigin默认值为false,但我们一般将changeOrigin值设为true
*/
pathRewrite: {'^/api1': ''} //去除请求前缀,保证交给后台服务器的是正常请求地址(必须配置)
}),
proxy('/api2', {
target: 'http://localhost:5001',
changeOrigin: true,
pathRewrite: {'^/api2': ''}
})
)
}
说明:
- 优点:可以配置多个代理,可以灵活的控制请求是否走代理。
- 缺点:配置繁琐,前端请求资源时必须加前缀。
使用
axios.get('http://localhost:3000/api1/students')
.then(data => {
console.log(data);
})
.catch(err => {console.log('失败了', err);});
fetch
-
特点
- fetch: 原生函数,不再使用XmlHttpRequest对象提交ajax请求
- 老版本浏览器可能不支持
-
相关API
-
GET请求
fetch(url).then(function(response) { return response.json() }).then(function(data) { console.log(data) }).catch(function(e) { console.log(e) });
-
POST请求
fetch(url, { method: "POST", body: JSON.stringify(data), }).then(function(data) { console.log(data) }).catch(function(e) { console.log(e) })
-
7、React-router-dom(web用)
理解
- react的一个插件库
- 专门用来实现SPA应用
- 基于react的项目基本都会用到
内置组件
-
:history router----------类似于vue路由配置的mode:history
-
:hash router--------------类似于vue路由配置的mode:hash;刷新会导致state参数丢失
-
- vue的redirect配置,放在注册路由最后
- 当所有路由都无法匹配时,跳转到redirect指定的路由
<Switch> <Route path="/about" component={About} /> <Route path="/home" component={Home} /> <Redirect to="/home"/> </Switch>
- =
-
----------------:用于显示高亮;to: 路径;children:标签体的内容;默认所有的link都会从上往下寻找判断
-
------------------包裹navlink,用于选择路由,如果匹配路由正确,则不继续往下寻找。 <Switch> <Route path="/about" component={About} /> <Route path="/home" component={Home} /> </Switch>
其他对象
- history对象
- match对象
- withRouter函数
安装
npm i react-router-dom --save
实现
-
首先在index.js中App组件包裹BrowserRouter
-
路由按钮----------------类似于vue的router-link
import {BrowserRouter, Link} from 'react-router-dom'; <Link className="list-group-item" to="/about" children="About" /> <Link className="list-group-item" to="/home">Home</Link>
-
注册路由
import {Route} from 'react-router-dom'; <Route path="/about" component={About} /> <Route path="/home" component={Home} />
-
路由组件默认带props:history、match、location
路由组件和一般组件的区别
-
1、写法不同
- 一般组件:
- 路由组件:
-
2、接收的props不同
-
一般组件:写组件标签时传递了什么,就收到什么
-
路由组件:接收到三个固定的属性
-
history:
-
- go: ƒ go(n)
- goBack: ƒ goBack() -------回退
- goForward: ƒ goForward() -------前进
- push: ƒ push(path, state)
- replace: ƒ replace(path, state)
-
location:
-
- pathname: “/home”
- search: “”
- state: undefined
- proto: Object
-
match:
-
- params: {}
- path: “/home”
- url: “/home”
-
-
出现多级路径后样式丢失问题
- 当出现多级路径时,一些css样式可能会丢失
- 解决方法-----------public/index.html
- 1、引入css时用绝对路径,不用…/、./相对路径
- 2、路径写:%PUBLIC_URL%/css…,public_url指根目录
- 3、使用hash路由:hashrouter,因为浏览器请求时遇到#后不会请求其后面的资源
路由的模糊匹配和严格匹配(少用)
-
模糊匹配---------可以匹配成功
<MyNavLink to="/home/a/b" children="Home" /> <Route path="/home" component={Home} />
-
严格匹配------Route添加属性exact={true}
<MyNavLink to="/home/a/b" children="Home" /> <Route exact={true} path="/home" component={Home} />
问题:可能会导致无法继续匹配二级路由
嵌套路由的使用
使用多级路由
<ul className="nav nav-tabs">
<li>
{/* <a className="list-group-item" href="./home-news.html">News</a> */}
<MyNavLink to="/home/news">News</MyNavLink>
</li>
<li>
{/* <a className="list-group-item" href="./home-message.html">Message</a> */}
<MyNavLink to="/home/message">Message</MyNavLink>
</li>
</ul>
<Switch>
<Route path="/home/news" component={News} />
<Route path="/home/message" component={Message}/>
<Redirect to="home/news"/>
</Switch>
重点
- 注册子路由时带上父路由的path值
- 路由的匹配是按照注册路由的顺序执行的,先最外层的路由,后内部的路由
向路由传递参数
传递params参数
-
Link向路由传参
<Link to={ `/home/message/detail/${messageObj.id}/${messageObj.title}`}>{messageObj.title}</Link>
-
Route声明接收参数
<Route path="/home/message/detail/:id/:title" component={Detail}/>
-
路由组件获取params参数
const {id, title} = this.props.match.params
传递search参数
-
Link向路由传参
<Link to={`/home/message/detail?id=${messageObj.id}&title=${messageObj.title}`}>{messageObj.title}</Link>
-
Route声明接收参数------无需声明,正常注册路由
<Route path="/home/message/detail" component={Detail} />
-
路由组件获取search参数--------在this.props.location.search中,需自行转为对象
//通过querystring将urlencoded转为对象 import qs from 'querystring'; const {id, title} = qs.parse(this.props.location.search.slice(1)); //search中为query参数字符串,自带问号,用slice截掉问号,再用parse转为对象
传递state参数
-
特点:不在url中显示
-
与state属性无关
-
Link向路由传参
<Link to={{ pathname: '/home/message/detail', state: { id: messageObj.id, title: messageObj.title}}}>{messageObj.title}</Link>
-
Route声明接收参数------无需声明,正常注册路由
<Route path="/home/message/detail" component={Detail} />
-
路由组件获取search参数--------在this.props.location.state中
const { id, title } = this.props.location.state || {};
push和replace
-
Link默认为push
-
修改为replace模式
<Link replace={true} to="/home" children="Home" />
代码实现路由跳转
-
使用this.props.history.push/replace(‘路径’, state);
//params this.props.history.push(`/home/message/detail/${id}/${title}`); //state this.props.history.push(`/home/message/detail`, state);
withRouter的使用
-
一般组件使用路由方法
-
引入withRouter
import {withRouter} from 'react-router-dom'; class Header extends Component {...}; export default withRouter(Header);
-
作用:使一般组件拥有路由组件的三个属性
8、ant-design(蚂蚁金服)-UI组件的使用
安装
npm i antd --save
使用
//引入组件
import { Button } from "antd";
//引入组件css
import 'antd/dist/antd.css';
//使用
//照着文档
样式的按需引入
- 看文档3.x或4.x
自定义主题
- 看文档4.x
9、打包react项目
npm run build