美文网首页
前端路由

前端路由

作者: 卓三阳 | 来源:发表于2018-06-05 22:38 被阅读53次

早期传统的服务端路由,直接根据 url 来 reload 页面,页面变得越来越复杂服务器端压力变大。随着 ajax 的出现,页面实现非 reload 就能刷新数据,也给前端路由的出现奠定了基础。单页面应用的实现,就是因为前端路由。

单页应用(SPA)应运而生。在url地址改变的过程中,通过js来实现不同UI之间的切换(js对DOM的操作),而不再向服务器重新请求页面,只通过ajax向服务端请求数据,对用户来说这种无刷新的、即时响应是更好的体验。


1.PushState (history.pushState()+popState事件)

原理:HTML5中history对象上新的API,同样能实现前端的路由。通过pushState()方法或replaceState()方法可以修改url的地址,并在popstate事件中能监听地址的改变,不同的是,手动的进行pushState()并不会触发popstate事件。
API: history.pushState 和 history.replaceState
两个 API 都会操作浏览器的历史记录,而不会引起页面的刷新,pushState会增加一条新的历史记录,而replaceState则会替换当前的历史记录。

用history实现一个前端路由
主要代码:

<body>
  <div class="menu">
    <a href="/home/">首页</a>
    <a href="/profile">个人中心</a>
    <a href="/articles">文章列表</a>
  </div>
  <div class="content">
    
  </div>
</body>

<script>
  window.onload=function(){
  const $ = (selector) => document.querySelector(selector);

  class Router {
      constructor (routeMap) {
          this.routeMap = routeMap;
          this._bindPopState();
      }
      init (path) {
          path = Router.correctPath(path);
          history.replaceState({path: path}, '', path);
          this.routeMap[path] && this.routeMap[path]();
      }
      go (path) {
          path = Router.correctPath(path);
          history.pushState({path: path}, '', path);
          this.routeMap[path] && this.routeMap[path]();
      }
      _bindPopState () {
          window.addEventListener('popstate', (e) => {
             const path = e.state && e.state.path;
             this.routeMap[path] && this.routeMap[path]();
          });
           }
      static correctPath (path) {
          if (path !== '/' && path.slice(-1) === '/') {
              // console.log(path.match(/(.+)\/$/i))
              path = path.match(/(.+)\/$/)[1];
          }
          return path;
      }
  }

  const routeMap = {
      '/home': () => {
          const content = $('.content');
          content.innerHTML = '<div>welcome to Home Page</div>';
      },
      '/profile': () => {
          const content = $('.content');
          content.innerHTML = '<div>welcome to Profile Page</div>';
      },
      '/articles': () => {
          const content = $('.content');
          content.innerHTML =
              '<div>' +
              '<p>welcome to Article Page</p>' +
              '<ul>' +
              '<li>文章1</li>' +
              '<li>文章2</li>' +
              '<li>文章3</li>' +
              '</ul>' +
              '</div>';
      }
  };

  const router = new Router(routeMap);
  router.init(location.pathname);
  $('.menu').addEventListener('click', (e) => {
      if (e.target.tagName === 'A') {
          e.preventDefault();
          router.go(e.target.getAttribute('href'))
      }
  });

}

</script>
res.png

window.onpopstate


2.Hash(location.hash+hashchange事件)

原理:url 中常会出现 #,一可以表示锚点(如回到顶部按钮的原理),二是路由里的锚点(hash)。Web 服务并不会解析 hash,也就是说 # 后的内容 Web 服务都会自动忽略,但是 JavaScript 是可以通过 window.location.hash 读取到的,读取到路径加以解析之后就可以响应不同路径的逻辑处理。

hashchange 事件(监听 hash 变化触发的事件),当用 window.location 处理哈希的改变时不会重新渲染页面,而是当作新页面加到历史记录中,这样我们跳转页面就可以在 hashchange 事件中注册 ajax 从而改变页面内容。

<body>
  <div class="menu">
    <a href="#/home/">首页</a>
    <a href="#/profile">个人中心</a>
    <a href="#/articles">文章列表</a>
  </div>
  <div class="content">
    
  </div>
</body>

<script>
  window.onload=function(){

  const $ = (selector) => document.querySelector(selector);
  function Router(routeMap){
      this.routeMap = routeMap;
  }

  Router.prototype={
    constructor:Router,
    init:function(path) {
          window.addEventListener('hashchange',this.go.bind(this),false);
          path = this.correctPath(path);
          this.routeMap[path] && this.routeMap[path]();
      },
     go:function () {
          var path = location.hash;
          path=this.correctPath(path);
          this.routeMap[path] && this.routeMap[path]();
      },
     correctPath:function(path) {
          path=path.slice(1);
          if (path !== '/' && path.slice(-1) === '/') {
              // console.log(path.match(/(.+)\/$/i))
              path = path.match(/(.+)\/$/)[1];
          }
          // console.log(path)
          return path;
      }
  }

  const routeMap = {
      '/home': () => {
          const content = $('.content');
          content.innerHTML = '<div>welcome to Home Page</div>';
      },
      '/profile': () => {
          const content = $('.content');
          content.innerHTML = '<div>welcome to Profile Page</div>';
      },
      '/articles': () => {
          const content = $('.content');
          content.innerHTML =
              '<div>' +
              '<p>welcome to Article Page</p>' +
              '<ul>' +
              '<li>文章1</li>' +
              '<li>文章2</li>' +
              '<li>文章3</li>' +
              '</ul>' +
              '</div>';
      }
  };

  const router = new Router(routeMap);
  router.init(location.hash);
}
</script>

3.前端路由优缺点

优点

用户体验好,不需要每次都从服务器全部获取,快速展现给用户

缺点

不利于SEO
使用浏览器的前进,后退键的时候重新发送请求,没有合理利用缓存


好文推荐
浅谈前端路由

相关文章

  • 第三十一节:Vue路由:前端路由vs后端路由的了解

    1. 认识前端路由和后端路由 前端路由相对于后端路由而言的, 在理解前端路由之前先对于路由有一个基本的了解 路由:...

  • 前端微服务化解决方案5 - 路由分发

    路由分发式微前端 从应用分发路由到路由分发应用 用这句话来解释,微前端的路由,再合适不过来. 路由分发式微前端,即...

  • vue - 路由模式

    1 路由的基本概念与原理 路由的本质就是对应关系; 在开发中, 路由分为前端路由和后端路由. 1.1 前端路由 概...

  • react-router-dom

    一、什么是前端路由 在我看来,前端路由和网络上的路由器功能很像。前端路由也是进行分发操作,只不过其分发的是页面跳转...

  • vue基础-路由(重要)

    前端路由的概念与原理 什么是前端路由 Hash 地址与组件之间的映射关系,前端路由可以将hash地址和组件关联起来...

  • CreateReactApp+ReactRouter4的使用

    路由基础介绍1,什么是前端路由? 路由是根据不同的 url 地址展示不同的内容或页面 前端路由就是把不同路由对应不...

  • 面试:谈谈对前端路由的理解?

    面试官想听到什么答案呢? 1、为什么会出现前端路由。 2、前端路由解决了什么问题。 3、前端路由实现的原理是什么。...

  • 前端路由(一)

    前端路由之变化url不发送请求 什么是路由?为什么要有前端路由? 首先,域名的组成:http://(协议)www....

  • vue学习笔记——vue-router

    1.什么是前端路由? 前端路由是根据不同的URL地址显示不同的内容或页面。 2.什么时候使用前端路由? 在单页面应...

  • vue-router 原理

    1、前端路由 在 Web 前端单页应用 SPA(Single Page Application)中,路由描述的是 ...

网友评论

      本文标题:前端路由

      本文链接:https://www.haomeiwen.com/subject/ihymsftx.html