这是我参与11月更文挑战的第16天,活动详情查看:2021最后一次更文挑战
背景
学习前端三个月了,准备刷刷面试题,总结总结,一天几道面试题,向大厂进军。
如果你是用React开发应用,你一定用过React-Router吧,哪你真清楚HashBrouter和BrowserRouter的区别吗??我们什么时候用HashRouter,什么时候使用BrowerRouter呢??
示例
我们先来看看React中如何使用React-Router吧?
import { HashRouter } from "react-router-dom";
render(){
<Provider store={store}>
<HashRouter>
<App />
</HashRouter>
</Provider>
}
这里使用的是HashRouter
我们在看看使用BrowserRouter
import { BrowserRouter } from "react-router-dom";
render(){
<Provider store={store}>
<BrowserRouter>
<App />
</BrowserRouter>
</Provider>
}
以往都是有人给我们搭好项目框架,我直接使用,也不关心路由,当你一个人搭建框架的时候,你就会考虑这个问题了?为什么要用这个路由??
前端路由实现方式
路由需要实现三个功能:
- 当浏览器地址变化时,切换页面;
- 点击浏览器后退,前进按钮,网页内容发生变化;
- 刷新浏览器,页面加载内容对应当前路由对应的地址;
在单页面web网页中,单纯的浏览器地址改变,网页不会重载,如单纯的hash值改变,网页是不会变化的,因此我们的路由需要监听事件,并利用js实现动态改变网页。
- hash 模式:监听浏览器地址hash值变化,并执行相应的js切换。
- history 模式:利用H5 history API实现url地址改变,网页内容改变。
hash模式
使用window.location.hash 属性和window.onhashchange事件。可以监听浏览器hash值得变化,去执行相应的js切换网页。
hash路由实现原理:
- hash 指的是地址中 # 号以及后面的字符。称为散列值。
- 散列值不会随请求发送到服务器端的,所以改变hash,不会重新加载界面。
- 监听onhashchange事件,hash改变时,可以通过window.location.hash来获取和设置hash值。
- location.hash值的变化直接反应在浏览器的地址栏。
history模式
我们使用history首先应该了解window.history对象。它表示的是当前窗口的浏览历史,当发生改变时,只会改变路径,不会刷新界面。
History对象就是一个堆栈。
方法:
History.back:移动上一个网址,等同于浏览器的后退。
History.forward:移动到下一个网址,等同于浏览器前进。
History.go:接受一个参数,以当前网页为基准,来进行跳转。默认history.go(0),刷新当前界面。
history.go(1) 相当与history.forward();
History.pushState():往history堆栈中添加一条记录。不会刷新界面,只会导致History对象变化,地址栏发生变化。
History.replaceState():是替换当前history堆栈中最上层的记录。也是不会刷新界面,只会是Histoty对象变化,地址栏发生变化。
每当history对象发生变化,就会触发popstate事件: window.addEventListener("popstate",function(){})
只调用pushState或者replaceState是不会触发改事件的,只有调用back,forward,go才会触发该事件。
至此我们也能想到BrowserHisory是怎么利用History的API来实现url改变,网页内容发生改变。
区别,我们该怎么选择
底层原理不一样:
BrowserRouter调用的是H5 history API,低版本兼容性问题。
HashRouter 使用的是URL哈希值
地址栏表现形式不一样:
BrowserRouter的路径:localhost:3000/demo/a
HashRouter的路径:localhost:3000/#/demo/a
刷新后对路由state参数的影响
BrowserRouter没有任何影响,因为state保存在history对象中。
HashRouter刷新后会导致路由state参数的丢失!!!
官方会更推荐使用browserRouter
,貌似是因为其构建于H5的History API
,比起hashRouter
,它多出了更多的方法操控url。
本人建议:前端路由使用HashRouter ,服务路由使用BrowerRouter
结语
一步一步慢慢来,踏踏实实把活干!