文章目录
一、前端路由
路由:管理页面之间的关系,不同的页面的路径不同,但是都承载在一个HTML文件中,路径不同,会加载不同的内容。
SPA:单页面应用-渲染速度快。
1、从用户的角度看,前端路由主要实现了两个功能(使用ajax更新页面状态的情况下):
①记录当前页面的状态(保存或分享当前页的url,再次打开该url时,网页还是保存(分享)时的状态);
②可以使用浏览器的前进后退功能(如点击后退按钮,可以使页面回到使用ajax更新页面之前的状态,url也回到之前的状态)。
2、作为开发者,要实现这两个功能,我们需要做到:
改变url且不让浏览器向服务器发出请求;
监测 url 的变化;
截获 url 地址,并解析出需要的信息来匹配路由规则。
3、前端路由的本质是监听url变化
,然后匹配路由规则
,无需刷新就可以显示相应的页面,目前单页面路由主要有以下两种方式。
我们路由常用的hash模式
和history模式
实际上就是实现了上面的功能。
二、hash模式
这里的 hash 就是指 url 尾巴后的 # 号以及后面的字符
。这里的 # 和 css 里的 # 是一个意思。hash也称作锚点
,本身是用来做页面定位的,它可以使对应 id 的元素显示在可视区域内。
由于 hash 值变化不会导致浏览器向服务器发出请求,而且 hash 改变会触发 hashchange 事件,浏览器的进后退也能对其进行控制,所以人们在 html5 的 history 出现前,基本都是使用 hash 来实现前端路由的。
例如使用到的api:
window.location.hash = 'qq' // 设置 url 的 hash,会在当前url后加上 '#qq'
var hash = window.location.hash // '#qq'
window.addEventListener('hashchange', function(){
// 监听hash变化,点击浏览器的前进后退会触发
})
三、history模式
hash 本来是拿来做页面定位的,如果拿来做路由的话,原来的锚点功能就不能用了。
hash 的传参是基于 url的,如果要传递复杂的数据,会有体积
的限制,而history 模式不仅可以在url里放参数,还可以将数据存放在一个特定的对象中,可以监听浏览器的前进、后退事件(back、forward、go)。
主要通过history.pushState/replceState向当前历史记录中插入状态对象state,在浏览器前进、回退、跳转等动作发生时触发popState事件,此时可以通过解析popState事件回调函数的event参数中的state对象,或者解析当前页面url来实现路由。
建议解析url方式实现路由。如果没有在页面首次加载的时候设置pushState/replaceState,那么首页一般是没有state对象的,在执行浏览器动作时,如果回退到首页,那么当前history对象的state属性不存在,导致解析state报错
相关API:
window.history.pushState(state, title, url)
// state:需要保存的数据,这个数据在触发popstate事件时,可以在event.state里获取
// title:标题,基本没用,一般传 null
// url:设定新的历史记录的 url。新的 url 与当前 url 的 origin 必须是一樣的,否则会抛出错误。url可以是绝对路径,也可以是相对路径。
例如:
当前url是 https://www.baidu.com/a/,执行history.pushState(null, null, ‘./qq/’),则变成 https://www.baidu.com/a/qq/,执行history.pushState(null, null, ‘/qq/’),则变成 https://www.baidu.com/qq/。
window.history.replaceState(state, title, url)
// 与 pushState 基本相同,但她是修改当前历史记录,而 pushState 是创建新的历史记录
window.addEventListener("popstate", function() {
// 监听浏览器前进后退事件,pushState 与 replaceState 方法不会触发
});
window.history.back() // 后退
window.history.forward() // 前进
window.history.go(1) // 前进一步,-2为后退两步,window.history.length可以查看当前历史堆栈中页面的数量
四、两种路由方式的差异
(1)方式的异同
①页面手动刷新,hash模式不会向服务器发送请求,history模式会;
②hash模式下url中的哈希值不会发送到服务器,history模式url全部会发送至服务器;
③设置location.hash和pushState都不会导致浏览器刷新;
④设置location.hash的时候会触发hashchange事件和popstate事件;
⑤仅当pushState函数设置url参数的值为hash格式时,浏览器动作发生会触发hashchange事件,尽管location.hash值为空;
⑥a标签锚点跳转可以设置hash,触发hashchange事件。
(2)注意的问题
如果pushState的url为跨域网址,那么会报错,这样设计的目的是防止恶意代码让用户以为他们是在另一个网站上。
五、React的页面路由模块:react-router-dom的使用
1、安装
npm install react-router-dom
2、实现路由模式的组件(决定路由模式)
其实就是路由的hash和history两种模式,并且这两个组件是路由的容器
,必须在最外层
。
(1)HashRouter组件:实现hash模式的路由
// hash模式
ReactDOM.render(
<HashRouter>
<Route path="/" component={
Home}/>
</HashRouter>
)
(2)BrowserRouter组件:实现history模式的路由
// history模式
ReactDOM.render(
<BrowserRouter>
<Route path="/" component={
Home} />
</BrowserRouter>
)
3、Route组件
路由的一个原材料,是控制路径对应显示的组件,即为实现路径和显示组件之间的映射。
Route的参数:
path:
跳转的路径
component:
对应路径显示的组件
render:
可以自己写render函数返回具体的dom,而不需要去设置component
location:
传递route对象,和当前的route对象对比,如果匹配则跳转
exact:
匹配规则,默认值