hash路由和history路由原理
-
vue-router的两种路由模式
-
hash路由
-
hash是URL的一个组成部分,由URL地址以#开头到末尾,我们可以使用
location.hash
获取hash值,a标签就是使用改变hash值来进行页面跳转也可做页面的锚点使用,实现锚点跳转<!-- 相当于 router-link --> <a href="./#home">首页</a> | <a href="./#about">关于我们</a> | <a href="./#introduce">公司介绍</a> <!-- 路由输出 相当于router-view --> <div id="router-view"></div> <script src="./js/router.js"></script>
-
创建一个router.js文件 利用hashchange事件监听hash值的变化
// 定义一个函数返回一个div元素 接收两个参数 id为页面div id属性 text为页面文本 const importCom = (id, text) => { const el = document.createElement('div') el.id = id el.innerHTML = text return el } // 配置路由表 const routes = [ { path: 'home', component: importCom('home', '欢迎光临公司首页') }, { path: 'about', component: importCom('about', '以客户为中心,以奋斗者为本!') }, { path: 'introduce', component: importCom('introduce', '互联网知名企业') }, { path: 'notFound', component: importCom('notFound', '页面不能找到!') }, ] // 添加路由,默认home const router = () => { const url = location.hash.slice(1) || 'hom' // 获取hash值 初始页面可能没有 设置默认hash值home const rootEle = document.querySelector('#router-view') // 获取页面路由输出根节点 rootEle.innerHTML = '' //清空原内容 const childEle = routes.find(item => item.path == url)?.component // 查找路由组件 // 页面添加路由组件 rootEle.appendChild(childEle ? childEle : routes.find(item => item.path == 'notFound')?.component) } router() //初始化执行 // hash值变化监听,变化后再次执行router window.addEventListener('hashchange', router)
-
-
history
-
history为浏览器URL的记录 有两个方法
-
putState(state,title,url)
- 保留现有的记录,将url加到历史记录中
-
replaceState(state,title,url)
- 将历史记录中的当前页面替换成url
-
这两个方法都是为了将当前url储存到历史记录中
-
title为记录标题 基本不用,使用null,state为合法的js对象,可以用在popstate中,popstate事件在
-
用户点击浏览器的前进、后退按钮
-
代码中调用history.back() 、history.forward()、history.go()
-
a 标签的锚点
-
当history对象发生变化时,就会触发popState事件。通过event.state可以访问当前历史记录的状态对象的拷贝。
当网页加载时,各浏览器对popstate事件是否触发有不同的表现,Chrome 和 Safari会触发popstate事件,而Firefox不会。
-
-
附:e.target.tagName 返回当前标签的大写状态
location.pathname 返回url中的目录和(或)文件名
-
-
代码实现,与hash的实现方式很类似
<!-- 相当于 router-link --> <nav id='nav'> <a href="./home">首页</a> | <a href="./about">关于我们</a> | <a href="./introduce">公司介绍</a> </nav> <!-- 路由输出 相当于router-view --> <div id="router-view"></div> <script src="./js/router.js"></script>
-
router.js
const importCom = (id, text) => { const el = document.createElement('div') el.id = id el.innerHTML = text return el } /*** 路由表 */ const routes = [ {path: 'home', component: importCom('home', '欢迎光临公司首页')}, { path: 'about', component: importCom('about', '以客户为中心,以奋斗者为本!')}, { path: 'introduce', component: importCom('introduce', '互联网知名企业')}, { path: 'notFound', component: importCom('notFound', '页面不能找到!')}, ] /*** 添加路由,默认home */ const router = () => { const url = location.pathname.slice(1) || 'home' const rootEle = document.querySelector('#router-view') rootEle.innerHTML = '' const childEle = routes.find(item => item.path == url)?.component rootEle.appendChild(childEle ? childEle : routes.find(item => item.path == 'notFound')?.component) } //事件委托给a标签绑定事件,监听切换 const navEle = document.querySelector('#nav') navEle.addEventListener('click', function (e) { if (e.target.tagName == 'A') { e.preventDefault() console.log(e.target.getAttribute('href')) const href = e.target.getAttribute('href').slice(1) history.pushState(null, `页面标题`, href) // 相当于 push // history.replaceState(null, `页面标题`, href) //相当于replace // 以上两个方法一样的效果 router() // 这里不要忘记执行 } })
-
-
总结
hash 模式:
#后面 hash 值的变化,不会导致浏览器向服务器发出请求,浏览器不发出请求,就不会刷新页面通过监听 hashchange 事件可以知道 hash 发生了哪些变化,然后根据 hash 变化来实现更新页面部分内容的操作。
history 模式:
history 模式的实现,主要是 HTML5 标准发布的两个 API,pushState 和 replaceState,这两个 API 可以改变 url,但是不会发送请求。这样就可以监听 url 变化来实现更新页面部分内容的操作。
区别
url 展示上,hash 模式有“#”,history 模式没有
刷新页面时,hash 模式可以正常加载到 hash 值对应的页面,而 history 没有处理的话,会返回 404,一般需要后端将所有页面都配置重定向到首页路由
兼容性,hash 可以支持低版本浏览器和 IE。
————————————————
版权声明:本文为CSDN博主「Zswsown」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_44385241/article/details/109245740