概念
在说到router的一个概念,我们需要先明白另一个概念, 站点。
- 无论是使用Vue,还是React,开发的单页应用程序,可能只是该站点的一部分(某一个功能块)
- 一个单页应用里,可能会划分为多个页面(几乎完全不同的页面效果)(组件)
如果要在单页应用中完成组件的切换,需要实现下面两个功能:
1.根据不同的页面地址,展示不同的组件(核心)
2.完成无刷新的地址切换
我们把实现了以上两个功能的插件,称之为路由,
- Vue 官方提供了一个路由的插件—— vue-router
- React的话,官方提供了一个核心插件——react-router, 如果是在dom中的话,那么使用react-router-dom,如果是native的话,那么使用react-router-native。这两个库都是基于react-router进行拓展的,意味着按照任意一个库都会帮我们按照上核心库。
原理
不管是vue 还是 react 的路由,都是有两种模式的:
- hash模式
- history模式
地址的组成成分
就随便拿一个地址来分析,如下图:
1.协议名(schema):https
2.主机名(host):csdnnews.blog.csdn.net
1.ip地址
2.预设值:localhost
3.域名
4.局域网中电脑名称
3.端口号(port):443
1.如果协议是http,端口号是80,则可以省略端口号
2.如果协议是https,端口号是443,则可以省略端口号
4.路径(path):/article/details/115713578
5.地址参数(search、query):?a=1&b=2
1.附带的数据
2.格式:属性名=属性值&属性名=属性值…
6.哈希(hash、锚点):#maodian
1.附带的数据
Hash Router 哈希路由
根据url地址中的哈希值来确定显示的组件,在#后面出现的任何字符,都会被浏览器解读为位置标识符。这意味着,这些字符都不会被发送到服务器端。因此,hash的变化会使浏览器只会滚动到相应位置,不会重新加载网页。所以#(sharp)被用来当作锚点,这也是为啥vue中的hash模式不能使用锚点来定位了。每一次改变#后的部分,都会在浏览器的访问历史中增加一个记录,使用"后退"或者“前进”按钮,就可以回到上一个位置。
监听hash 变化
监听hash的变化,浏览器提供了hashchange的方法,注册这个方法后就可以监听hash的变化了,并且获取当前hash的方法是 location.hash
// dom加载完成 document.addEventListener('DOMContentLoaded', () => { alert('hash变化了,当前的hash是:'+location.hash); }) // hash变化后,就会执行下面的方法 window.addEventListener('hashchange', () => { alert('hash变化了,当前的hash是:'+location.hash); })
原因
hash的变化,不会导致页面刷新
这种模式的兼容性最好,能兼容好久以前的浏览器,但是也有一个
History Router 浏览器历史记录路由
HTML5出现后,新增了History Api,从此以后,浏览器拥有了改变路径而不刷新页面的方式。History表示浏览器的历史记录,它使用栈的方式存储。如果你使用 history.pushState('第一个组件',null,'/123') 这个H5 里面的api来改变地址(path),浏览器是不会刷新页面的。本质上是监听 popstate事件.
注意: pushState 和 replaceState 这两个方法是不会触发 popstate 事件的, 如果想要监听他两个的行为,那么直接把这两个方法变异处理一下,类似 vue2中的变异数组方法一样。
document.addEventListener('DOMContentLoaded', () => { alert('地址发生变化了,当前的path是:' + location.pathname); }) window.addEventListener('popstate', () => { alert('地址发生变化了,当前的path是:' + location.pathname); })
1.history.length:获取栈中数据量
2.history.pushState:向当前历史记录栈中加入一条新的记录
1.参数1:附加的数据,自定义的数据,可以是任何类型
2.参数2:页面标题,目前大部分浏览器不支持
3.参数3:新的地址
3.history.replaceState:将当前指针指向的历史记录,替换为某个记录
1.参数1:附加的数据,自定义的数据,可以是任何类型
2.参数2:页面标题,目前大部分浏览器不支持
3.参数3:新的地址
根据页面的路径决定渲染哪个组件