路由
一、路由
路由的基本使用我们已经讲过了,现在讲讲路由传参。
1.1、路由传参
路由传参完成的是组件之间的数据传递(组件传值)
1)、params
- 路由配置
<Route path='/Inbox/:id' component={Inbox} />
- 路由跳转(传值)
//声明式导航:
<NavLink to={'/Inbox/01008'} >铅笔</NavLink>
//编程式导航:
this.props.history.push( '/Inbox/'+'01008' )
- 取值
this.props.match.params.id
优缺点:
优势 : 刷新,参数依然存在。
缺点 : 只能传字符串,并且,如果传的值太多的话,url会变的很长。
2)、query
- 路由配置
不用改变路由配置(类似于vue路由中的query)
<Route path='/Inbox' component={Inbox} />
- 路由跳转(传值)
//声明式导航:
<Link to={{pathname:'/Inbox',query:{id:'01009'}}} >铅笔</Link>
//编程式导航:
this.props.history.push( {pathname:'/Inbox',query:{id:'01009'}} )
- 取值
this.props.location.query.id
优缺点:
优势:参数不显示在地址栏,美观;
缺点:刷新地址栏,参数丢失
3)、state
类似于query,只是state传的参数是加密的,query传的参数是公开的,使用方法只需要把query改为state即可。
- 路由配置
不用改变路由配置。
<Route path='/Inbox' component={Inbox} />
- 路由跳转(传值)
//声明式导航
<Link to={{pathname:'/Inbox',state:{id:'01009'}}} >铅笔</Link>
//编程式导航
this.props.history.push({pathname:'/Inbox',state:{id:"01"}});
- 取值
this.props.location.state.id
优缺点:
优势:参数不显示在地址栏,美观;
缺点:刷新地址栏,(hash方式会丢失参数,Browser模式不会丢失参数)。
4)、search
- 路由配置
不用改变路由配置。
<Route path='/Inbox' component={Inbox} />
- 传值
//声明式导航
<Link to='/Inbox?a=1&b=2' >铅笔</Link>
//编程式导航
this.props.history.push({pathname:'/Inbox',search:'?a=1&b=2'})
- 取值
this.props.location.search
注意:
用location.search所获取的是查询字符串,所以,还需要进一步的解析,也可以使用第三方模块:qs,或者nodejs里的query-string
1.2、路由上下文
在react-router里面,如果组件是通过路由跳转的,那么它会把路由相关的API挂在了组件的props上(vue-Router使用的 r o u t e r 和 router和 router和route),并且分为history,location,match。
history: 历史,用来跳转的,并做历史记录。
location: 地址,地址栏上路径,并保存着query,state,search等数据。
match: 匹配,匹配到的路径
1.3、非路由跳转的组件获取路由上下文
在这之前,我们先看看组件在页面上展示的两种情况下,props对象的内容
1)、标签名的方式直接展示的组件(没有属性),值为空
2)、路由跳转的方式展示的组件,props会自动增加属性:history,match,location。
那么,
如果用标签名的方式,如何获取到路由上下文?往下看。
-
通过属性传递
首先当前组件是路由跳转过来的,然后把路由上下文通过属性的方式传递给子组件。
<AboutSub02 {...this.props} />
-
通过withRouter包装
接收路由上下文的组件用withRouter函数(高阶组件)进行包裹
如:
import {withRouter} from 'react-router-dom'
class 组件 extends Component{
}
export default withRouter(组件)
1.4、exact属性
react的路由匹配默认是模糊的,包容的,如果想使用严格匹配,那么,把Route组件的exact属性设置为true。
<Route exact={true} path="/" component={App} />
1.5、404
在路由配置里不设置path属性,那么,就总是会匹配上。404页面可以用(结合Switch)
<Route component={Error}/> 总是会匹配
1.6、Switch
排他性匹配
简单理解:匹配到第一个就不再匹配,除非地址改变。
区分:exact和switch
excat:表示匹配规则,exact={true} 表示地址栏的路径和路由配置中path必须完全相等才能匹配到。
switch:表示排他性,即:一旦匹配成功后,就不再匹配其它路由匹配。
1.7、Redirect
类似于vue中的重定向。(这里是一个组件)
<Redirect exact={true} from="/" to="/Home" />
react路由的一些扩展(了解):
组件及其作用:
组件 | 作用 | |
---|---|---|
路由模式 | BrowserRouter | 约定模式 为 history,使用 HTML5 提供的 history API 来保持 UI 和 URL 的同步 |
路由模式 | HashRouter | 约定模式 为 hash,使用 URL 的 hash 来保持 UI 和URL 的同步 |
声明式跳转 | NavLink | 声明式跳转 还可以约定 路由激活状态 |
声明式跳转 | Link | 声明式跳转 无激活状态 |
重定向 | Redirect | 重定向 ~~ replace |
匹配并展示 | Route | 匹配组件,并展示组件。即匹配成功后,组件立即被替换成匹配的组件 |
排他性匹配 | Switch | 排他性匹配。如果不想使用包容性,那么使用Switch。 |
高阶组件 | withRouter | 把不是通过路由切换过来的组件中,将 history、location、match 三个对象传入props对象上(高阶组件) |
结构
-
BrowserRouter|HashRouter
App(或其它组件)
- NavLink|Link
- Route
- Redirect
- 子组件
- NavLink|Link
- Route
- …
- 子组件
BrowserRouter
属性 | 类型 | 作用 |
---|---|---|
basename | string | 所有位置的基本URL。如果您的应用是从服务器上的子目录提供的,则需要将其设置为子目录。格式正确的基本名称应以斜杠开头,但不能以斜杠结尾 |
getUserConfirmation | Function | 用于确认导航的功能。默认使用window.confirm 。 |
Route
属性 | 类型 | 作用 |
---|---|---|
path | string |object | 路由匹配路径。没有path属性的Route 总是会 匹配 |
exact | boolean | 为true时,要求全路径匹配(/home)。路由默认为“包含”的(/和/home都匹配),这意味着多个 Route 可以同时进行匹配和渲染 |
component | Function |component | 在地址匹配的时候React的组件才会被渲染,route props也会随着一起被渲染 |
render | Function | 内联渲染和包装组件,要求要返回目标组件的调用 |
Link
属性 | 类型 | 作用 |
---|---|---|
to | string | 对象{pathname:,search:,hash:} | 要跳转的路径或地址 |
replace | boolean | 是否替换历史记录 |
NavLink
属性 | 类型 | 作用 |
---|---|---|
to | string|对象{pathname:,search:,hash:} | 要跳转的路径或地址 |
replace | boolean | 是否替换历史记录 |
activeClassName | string | 当元素被选中时,设置选中样式,默认值为 active |
activeStyle | object | 当元素被选中时,设置选中样式 |
Switch
该组件用来渲染匹配地址的第一个Route或者Redirect,仅渲染一个路由,排他性路由,默认全匹配(场景:侧边栏,引导选项卡等)
属性 | 类型 | 作用 |
---|---|---|
location | string object | |
children | node |
Redirect
该组件用来渲染匹配地址的第一个Route或者Redirect,仅渲染一个路由,排他性路由,默认全匹配(场景:侧边栏和面包屑,引导选项卡等
属性 | 类型 | 作用 |
---|---|---|
from | string | 来自 |
to | string object | 去向 |
push | boolean | 添加历史记录 |
exact | boolean | 严格匹配 |
sensitive | boolean | 区分大小写 |
二、选择器冲突解决方案
2.1、命名空间 BEM
BEM(Block, Element, Modifier)是由Yandex团队提出的一种前端命名规范。其核心思想是将页面拆分成一个个独立的富有语义的块
(blocks),十分有利于代码复用。
Block:代表块(Block):也是模块的意思
Element:元素(Element):
Modifier: 修饰符(Modifier)
2.2、模块化
import 变量 from './css/xx.module.css'
<jsx className={变量.类名|id}
//step1 (脚手架默认配置了)
webpack配置 "style-loader!css-loader?modules" | module:true
//step2 模块化时
改名xx.css -> xx.module.css
2.3、scss
- 安装: node-sass
npm i node-sass -S
- 引入sass
//1)、普通引入
import 'xx/xx.scss'
<jsx className="box" />
//2)、模块化
import style form xx.module.scss
<jsx className={style.box}
- 引入全局的(公共的)scss
- 局部scss文件内部: @import './全局.scss'
- webpack配置一次,局部scss内部直接使用
//1. 安装插件 : sass-resources-loader
//2. 配置修改webpack.config.js
{
test:sassRegex,
...
use: [
{loader:'style-loader'},
{loader:'css-loader'},
{loader:'sass-loader'},
{
loader: 'sass-resources-loader',
options:{
resources:'./src/xx/全局主题.scss'
}
}
]
}
注意:
loader:'css-loader?modules' ?modules 模块化时需要添加
resources 指向作用域在项目环境下
三、async和await
es7用来彻底解决回调地狱的问题。
具体的可以参考