第五章 React路由
SPA的理解(单页面多组件)
- 单页Web应用(single page web application,SPA)。
- 整个应用只有一个完整的页面。
- 点击页面中的链接不会刷新页面,只会做页面的局部更新。
- 数据都需要通过ajax请求获取, 并在前端异步展现。
什么是路由?
- 一个路由就是一个映射关系(key:value)
- key为路径, value可能是function或component
路由分类
- 后端路由:
1) 理解: value是function, 用来处理客户端提交的请求。
2) 注册路由:router.get(path, function(req, res))
3) 工作过程:当node接收到一个请求时, 根据请求路径找到匹配的路由, 调用路由中的函数来处理请求, 返回响应数据 - 前端路由:
1) 浏览器端路由,value是component,用于展示页面内容。
2) 注册路由:<Route path="/test" component={Test}>
3) 工作过程:当浏览器的path变为/test时, 当前路由组件就会变为Test组件
react-router-dom的理解
安装5版本的话 npm i react-router-dom@5
- react的一个插件库。
- 专门用来实现一个SPA应用。
- 基于react的项目基本都会用到此库。
路由的基本使用
- 明确好界面中的导航区、展示区
- 导航区的a标签改为Link标签
<Link to="/xxxxx">Demo</Link>
- 展示区写Route标签进行路径的匹配
<Route path='/xxxx' component={Demo}/>
<App>
的最外侧包裹了一个<BrowserRouter>
或<HashRouter>
路由组件与一般组件
- 写法不同:
一般组件:<Demo/>
路由组件:<Route path="/demo" component={Demo}/>
- 存放位置不同:
一般组件:components
路由组件:pages - 接收到的props不同:
一般组件:写组件标签时传递了什么,就能收到什么(不传就啥也收不到)
路由组件:接收到三个固定的属性
{ : width=54%}
NavLink
- NavLink可以实现路由链接的高亮,通过activeClassName指定样式名
点击到谁,谁就有这个activeClassName的样式了(因为项目里用了bootstrap,你在index.html设置这个样式要权重比bootstrap高才行),如果activeClassName等于active这个类,可以省了不写了,默认。
封装NavLink组件
- 标签体内容是一个特殊的标签属性
- 通过
this.props.children
可以获取标签体内容
Switch的使用
Swithch
包裹内的,一旦匹配上了就不会接着匹配了
- 通常情况下,path和component是一一对应的关系。
- Switch可以提高路由匹配效率(单一匹配)。
解决多级路径刷新页面样式丢失的问题
- public/index.html 中 引入样式时不写 ./ 写
/
(常用) - public/index.html 中 引入样式时不写 ./ 写
%PUBLIC_URL%
(常用) - 使用
HashRouter
public是dev-server服务器的根路径,当访问一个不存在的资源时,默认返回index.html
{: width=38%}
路由的严格匹配与模糊匹配
- 默认使用的是模糊匹配(简单记:
【输入的路径】必须包含要【匹配的路径】,且顺序要一致)
- 开启严格匹配:
<Route exact={true} path="/about" component={About}/>
- 严格匹配不要随便开启,需要再开,有些时候开启会导致无法继续匹配二级路由
Redirect的使用
- 一般写在所有路由注册的最下方,当所有路由都无法匹配时,跳转到Redirect指定的路由
- 具体编码:
<Switch>
<Route path="/about" component={About}/>
<Route path="/home" component={Home}/>
<Redirect to="/about"/>
</Switch>
嵌套路由
- 注册子路由时要写上父路由的
path
值 - 路由的匹配是
按照注册路由的顺序
进行的
向路由组件传递参数
1.params参数
路由链接(携带参数):`<Link to='/demo/test/tom/18'}>详情</Link>`
注册路由(声明接收):`<Route path="/demo/test/:name/:age" component={Test}/>`
接收参数:`this.props.match.params`
{: width=38%}
{: width=61%}
2.search参数
路由链接(携带参数):`<Link to='/demo/test?name=tom&age=18'}>详情</Link>`
注册路由(无需声明,正常注册即可):`<Route path="/demo/test" component={Test}/>`
接收参数:`this.props.location.search`
备注:获取到的search是urlencoded编码字符串,需要借助querystring解析
{: width=61%}
3.state参数(这个state和组件的那个state没有任何关系)
以前的to都是字符串,这里要写成对象,最外面的{ }代表表达式
路由链接(携带参数):`<Link to={{pathname:'/demo/test',state:{name:'tom',age:18}}}>详情</Link>`
注册路由(无需声明,正常注册即可):`<Route path="/demo/test" component={Test}/>`
接收参数:`this.props.location.state`
备注:刷新也可以保留住参数
{: width=61%}
push与replace
{: width=88%}
编程式路由导航
借助this.prosp.history对象上的API对操作路由跳转、前进、后退
-this.prosp.history.push()
-this.prosp.history.replace()
-this.prosp.history.goBack()
-this.prosp.history.goForward()
-this.prosp.history.go()
withRouter
的使用
- withRouter可以加工一般组件,让一般组件具备路由组件所特有的API
- withRouter的返回值是一个新组件
{: width=81%}
BrowserRouter与HashRouter的区别
- 底层原理不一样:
BrowserRouter使用的是H5的history API,不兼容IE9及以下版本。
HashRouter使用的是URL的哈希值。 - path表现形式不一样
BrowserRouter的路径中没有#,例如:localhost:3000/demo/test
HashRouter的路径包含#,例如:localhost:3000/#/demo/test 刷新后对路由state参数的影响
(1).BrowserRouter没有任何影响,因为state保存在history对象中
(2).HashRouter刷新后会导致路由state参数的丢失!!!
4.备注:HashRouter可以用于解决一些路径错误相关的问题。(比如样式丢失)
第六章 React UI组件库
流行的开源React UI组件库
material-ui(国外)
ant-design(国内蚂蚁金服)(建议,对工作有用
)
- 官网: https://ant.design/index-cn
- Github: https://github.com/ant-design/ant-design/
- 安装
yarn add antd
antd的按需引入+自定主题
- 安装依赖:yarn add react-app-rewired customize-cra babel-plugin-import less less-loader
- 修改package.json
....
“scripts”: {
“start”: “react-app-rewired start”,
“build”: “react-app-rewired build”,
“test”: “react-app-rewired test”,
“eject”: “react-scripts eject”
},
.... - 根目录下创建config-overrides.js
//配置具体的修改规则
const { override, fixBabelImports,addLessLoader} = require(‘customize-cra’);
module.exports = override(
fixBabelImports(‘import’, {
libraryName: ‘antd’,
libraryDirectory: ‘es’,
style: true,
}),
addLessLoader({
lessOptions:{
javascriptEnabled: true,
modifyVars: { ‘@primary-color’: ‘green’ },
}
}),); - 备注:不用在组件里亲自引入样式了,即:import ‘antd/dist/antd.css’应该删掉