Router
统一路由器管理
一个app用 一个 BroswerRouter 包裹
<Route path={'/about'} component={About}/>
<Route path={'/home'} component={Home} />
// 在路由器中注册路由,并且 该路由里的内容就展示在 Route这个标签的位置
<Link to={'/about'}>About</Link>
<Link to={'/home'}>Home</Link>
// 通过 Link标签进行跳转
路由组件 && 一般组件
路由组件会默认收到 传的props[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
一般组件不会
NavLink
点击NavLink 的时候,动态添加一个类。 activeClassName 指定添加的类名
所以我们通常对 NavLink 进行封装,将公共的部分,封装起来
问题:如何传递标签体的内容?
标签体内的内容通过 props.children
传递过来
// 一次性搞定
<NavLink activeClassName={Style.handsome} {...props}/>
// 标签体内容就是 props.children 里的内容,所以可以直接写 props.children 不写标签体,是一模一样的
路由配置存在的问题
<Route path={'/home'} component={Home} />
<Route path={'/home'} component={Test} />
// 路径一致了,会同时渲染 Home 和 Test
// 怎么让 匹配上之后,就不往后面匹配呢?
Switch...
<Switch>
<Route path={'/about'} component={About}/>
<Route path={'/home'} component={Home} />
<Route path={'/home'} component={Test} />
</Switch>
// 这个样子就会只匹配第一个
样式丢失
public 文件夹是 本地服务器的根路径。 请求了不存在的内容,就会返回public 里 的index.html
// 当请求路径为多重嵌套的时候
<Route path={'/tby/home'} component={Home} />
// 在请求样式的时候,会将 /tby 视为public下的路径,请求css 的路径会发生错误,于是请求失败
解决办法
- 相对路径改为绝对路径
- %PUBLIC_URL% 拼接到 /css 之前 只适用于脚手架
- 使用 HashRouter #/ 之后的全部都认为是前端的资源,不带给服务器
严格匹配 && 模糊匹配
模糊匹配: /home /sad/afad/asd 如果可以对上 /home 其他的随便写都可以匹配上
精准匹配:添加 exact
属性,就是完全的精准匹配
模糊匹配 出问题了再开启严格匹配,严格匹配有时候导致无法匹配二级路由
Redirect
重定向,放在Switch 的最后面,都没匹配上后,进入重定向
<Redirect to={'/about'}/>
嵌套路由
// 路由不要开启严格匹配模式,就可以这样来创建路由嵌套
<MyNavLink to={'/home/news'}>News</MyNavLink>
<MyNavLink to={'/home/message'}>About</MyNavLink>
// code ....
<Switch>
<Route path={'/home/news'} component={News}/>
<Route path={'/home/message'} component={Message}/>
<Redirect to={'home/news'}/>
</Switch>
路由传递参数
params 参数
利用 url 拼接传递参数
<Link to={`/home/message/detail/${item.id}/${item.title}`} key={item.id}>{item.title}</Link>
// item.id item.title
<Route path={'/home/message/detail/:id/:title'} component={Detail}/>
// 在定义路由的时候,用 :id :title 去接住
// 在 目的组件中
// props.match.params 这个属性中就可以获取到 .id .title 两个属性
search参数
传递的时候
<Link to={`/home/message/detail/?id=${item.id}&title=${item.title}`} key={item.id}>{item.title}</Link>
// 用 ? 分割
<Route path={'/home/message/detail'} component={Detail}/>
// 注册的时候不需要额外操作
接受的时候
// ? 后的参数 会被分割出来,保存到下列属性里 是一个 ?开头的字符串
props.location.search
// 利用 querystring 库
import qs from 'querystring'
const res = qs.parse(props.location.search.slice(1))
// res 一个对象,里有 id title 两个属性
// 至此,完成search参数传参
state参数
<Link to={{
pathname:'/home/message/detail',
state:{id:item.id,title:item.title}
}}
key={item.id}>{item.title}</Link>
// to 写成一个对象,要传的值存在 state 中
const {id,title} = props.location.state
// 在 子组件中就可以在 props.location.state 中查到 传递的参数
push与replace的区别
push 会留下痕迹,可以回退
replace 不会留下痕迹,不可以回退
编程式路由导航
利用 props.history 对象 进行操作
// params 参数
props.history.push(`/home/message/detail/${id}/${title}`)
// search 参数 同上
// state 参数
prop.history.push('home/message/detail',state)
withRouter
让非路由组件拥有 history location match 方法
BrowserRouter 和 HashRouter 的区别
-
底层原理不一样
BrowserRouter 使用的是 H5 的 history API, 不兼容 IE9以下版本
HashRouter 使用的是URL的哈希值
-
path 表现形式不一样
BrowserRouter没有#
HashRouter有 # 。 # 后面是默认不发送给服务器的
-
HashRouter 刷新之后参数会丢失