ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

前端路由原理之 hash 模式和 history 模式

2021-09-10 23:03:25  阅读:194  来源: 互联网

标签:about hash 模式 routerViewEl home pushState 路由 history


什么是路由?

个人理解路由就是浏览器 URL 和页面内容的一种映射关系。

比如你看到我这篇博客,博客的链接是一个 URL,而 URL 对应的就是我这篇博客的网页内容,这二者之间的映射关系就是路由。

其中路由又分为前端路由和后端路由,由于目前是大部门开发模式都是前后端分离开发模式,其大部分应用都是 SPA(simple Page Application,单页面应用),个人的工作也是由后端提供API,我前端来进行整个页面的渲染和路由控制。

前端路由目前实现的原理主要是:URL 的 hashHTML5 的 History

hash 模式

浏览器提供了一些 api 可以让我们获取到URL中带“#”的标识。比如 URL.hash、location.hash。

同时我们可以通过 hashchange 事件来监听hash值的改变,这样就能通过事件监听 url 中 hash 的改变从而改变特定页面元素的显示内容,从而实现前端路由。简单实现代码如下:
image

<div id="app">
	<a href="#/home">home</a>
	<a href="#/about">about</a>

	<div class="router-view"></div>
</div>
// 1.获取路由显示元素
const routerViewEl = document.querySelector('.router-view');

// 2.监听 hashchange 事件
window.addEventListener('hashchange', () => {
  // 3.判断 hash 的改变值,修改路由显示元素的 innerHTMl
  switch (location.hash) {
    case '#/home':
      routerViewEl.innerHTML = 'Home';
      break;
    case '#/about':
      routerViewEl.innerHTML = 'about';
      break;
    default:
      routerViewEl.innerHTML = 'default';
  }
});

History 模式

history 接口是 HTML5 新增的, 它有六种模式改变 URL 而不刷新页面。

  • pushState:使用新的路径;
  • replaceState:替换原来的路径;
  • popState:路径的回退;
  • go:向前或向后改变路径;
  • forward:向前改变路径;
  • back:向后改变路径;

其中比较重要的两个 api 是 pushState 和 replaceState 是比较重要的,是实现 history 模式的重要 api。

首先我们用 pushState 来简单实现下,代码如下:
image

<div id="app">
	<a href="/home">home</a>
	<a href="/about">about</a>

	<div class="router-view"></div>
</div>
// 1.获取路由显示元素
const routerViewEl = document.querySelector('.router-view');

// 2.获取所有路由跳转元素
const aEls = document.getElementsByTagName('a');
// 3.遍历所有 a 元素,注册事件监听点击
for (let aEl of aEls) {
  aEl.addEventListener('click', (e) => {
    // 4.阻止默认跳转
    e.preventDefault();
    // 5.获取 href 属性
    const href = aEl.getAttribute('href');
    // 6.执行 history.pushState
    history.pushState({}, '', href);
    // 7.判断 pathname 路径的改变
    switch (location.pathname) {
      case '/home':
        routerViewEl.innerHTML = 'Home';
        break;
      case '/about':
        routerViewEl.innerHTML = 'about';
        break;
      default:
        routerViewEl.innerHTML = 'default';
    }
  });
}

相同之处是两个 API 都会操作浏览器的历史记录,而不会引起页面的刷新。

不同之处在于,pushState 会增加一条新的历史记录,而 replaceState 则会替换当前的历史记录。其内部原理是 pushState 每次前进一次页面都是入栈操作,每次返回又是出栈,因此使用 pushState ,浏览器可以执行本身的前进后退操作,其内部就是一个入栈出栈;而 replaceState 就不可,它是把每次栈底的数据替换,而不是入栈。

pushState 栈:[]->点击 home 入栈->[home]->点击 about 入栈->[home,about]->浏览器回退,about 出栈->[home]
replaceState 栈:[]->点击 home 入栈->[home]->点击 about 替换栈底->[about]

如果把代码改成 replaceState 实现。那么就不能操作浏览器上面的前进后退操作。

image

// 1.获取路由显示元素
const routerViewEl = document.querySelector('.router-view');

// 2.获取所有路由跳转元素
const aEls = document.getElementsByTagName('a');
// 3.遍历所有 a 元素,注册事件监听点击
for (let aEl of aEls) {
  aEl.addEventListener('click', (e) => {
    // 4.阻止默认跳转
    e.preventDefault();
    // 5.获取 href 属性
    const href = aEl.getAttribute('href');
    // 6.执行 history.replaceState
    // history.pushState({}, '', href);
    history.replaceState({}, '', href);
    // 7.判断 pathname 路径的改变
    switch (location.pathname) {
      case '/home':
        routerViewEl.innerHTML = 'Home';
        break;
      case '/about':
        routerViewEl.innerHTML = 'about';
        break;
      default:
        routerViewEl.innerHTML = 'default';
    }
  });
}

参考文章

前端路由的两种实现原理

标签:about,hash,模式,routerViewEl,home,pushState,路由,history
来源: https://www.cnblogs.com/cqkjxxxx/p/15253331.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有