当前位置:   article > 正文

vue-router 原理_vue-router原理

vue-router原理

1、前端路由

在 Web 前端单页应用 SPA(Single Page Application)中,路由描述的是 URL 与 UI 之间的映射关
系,这种映射是单向的,即 URL 变化引起 UI 更新(无需刷新页面)。

vue-router 是 Vue.js 官方的路由插件,它和 vue.js 是深度集成的,适合用于构建单页面应用。

那与传统的页面跳转有什么区别呢?

  • vue 的单页面应用是基于路由和组件的,路由用于设定访问路径,并将路径和组件映射起来。
  • 传统的页面应用,是用一些超链接来实现页面切换和跳转的。

在 vue-router 单页面应用中,则是路径之间的切换,也就是组件的切换。路由模块的本质就是建立起 url 和页面之间的映射关系

2、包含的功能

Vue Router 包含的功能有:

  • 嵌套的路由/视图表
  • 模块化的、基于组件的路由配置
  • 路由参数、查询、通配符
  • 基于 Vue.js 过渡系统的视图过渡效果
  • 细粒度的导航控制
  • 带有自动激活的 CSS class 的链接
  • HTML5 历史模式或 hash 模式,在 IE9 中自动降级
  • 自定义的滚动条行为

3、vue-router 实现原理

在 vue-router 中,可以通过三种方式来实现前端路由的变化,分别为 hash、history 和 abstract。

3.1 hash

hash 是 URL 中 hash (#) 及后面的那部分,常用作锚点在页面内进行导航,最重要的是改变 URL 中的 hash 部分不会引起页面刷新。

我们可以通过 hashchange 事件监听 URL 的变化,改变 URL 的方式只有这几种:

  • 通过浏览器前进后退改变 URL
  • 通过``标签改变 URL
  • 通过window.location改变 URL

我们通过下面的例子,来看下 hash 实现路由的原理:

<!DOCTYPE html>
<html lang="en">
  <body>
    <ul>
      <ul>
        <!-- 定义路由 -->
        <li><a href="#/home">home</a></li>
        <li><a href="#/about">about</a></li>

        <!-- 渲染路由对应的 UI -->
        <div id="routeView"></div>
      </ul>
    </ul>
  </body>
  <script>
    let routerView = document.getElementById('routeView');
    window.addEventListener('hashchange', () => {
      routerView.innerHTML = location.hash;
    });
    window.addEventListener('DOMContentLoaded', () => {
      if (!location.hash) {
        //如果不存在hash值,那么重定向到#/
        location.hash = '/';
      } else {
        //如果存在hash值,那就渲染对应UI
        routerView.innerHTML = location.hash;
      }
    });
  </script>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

上面的代码很简单,只要注意一下几点:

  • 我们通过 a 标签的 href 属性来改变 URL 的 hash 值。当然,触发浏览器的前进后退按钮也可以,或者在控制台输入 window.location 赋值来改变 hash 都是可以的。也都会触发 hashchange。
  • 我们监听 hashchange 事件。一旦事件触发,就改变 routerView 的内容,若是在 vue 中,这改变的应当是 router-view 这个组件的内容。
  • 为何又监听了 load 事件?这时因为页面第一次加载完不会触发 hashchange,因而用 load 事件来监听 hash 值,再将视图渲染成对应的内容。

3.2 history

由于 html5 标准的发布,history 的 api 增加了两个 API。pushState 和 replaceState。通过这两个 API 可以改变 url 地址且不会发送请求。同时还有 popstate 事件。通过这些就能用另一种方式来实现前端路由了,但原理都是跟 hash 实现相同的。

用了 HTML5 的实现,单页路由的 url 就不会多出一个#,变得更加美观。但因为没有 # 号,所以当用户刷新页面之类的操作时,浏览器还是会给服务器发送请求。为了避免出现这种情况,所以这个实现需要服务器的支持,需要把所有路由都重定向到根页面。

我们主要说几个注意点:

  • 通过 pushState/replaceState 或标签改变 URL 不会触发页面刷新,也不会触发 popstate 方法。所以我们可以拦截 pushState/replaceState 的调用和标签的点击事件来检测 URL 变化,从而触发 router-view 的视图更新。
  • 通过浏览器前进后退改变 URL ,或者通过 js 调用 history 的 back,go,forward 方法,都会触发 popstate 事件,所以我们可以监听 popstate 来触发 router-view 的视图更新。

所以,我们其实是需要监听 popstate 以及拦截 pushState/placeState 以及 a 的点击去实现监听 URL 的变化。

我们通过下面的例子,来看下 history 实现路由的原理:

<!DOCTYPE html>
<html lang="en">
  <body>
    <ul>
      <ul>
        <li><a href="/home">home</a></li>
        <li><a href="/about">about</a></li>

        <div id="routeView"></div>
      </ul>
    </ul>
  </body>
  <script>
    let routerView = document.getElementById('routeView');
    window.addEventListener('DOMContentLoaded', () => {
      routerView.innerHTML = location.pathname;
      var linkList = document.querySelectorAll('a[href]');
      linkList.forEach(el =>
        el.addEventListener('click', function(e) {
          e.preventDefault();
          history.pushState(null, '', el.getAttribute('href'));
          routerView.innerHTML = location.pathname;
        }),
      );
    });
    window.addEventListener('popstate', () => {
      routerView.innerHTML = location.pathname;
    });
  </script>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

注意一下几个重点:

  • 我们监听 popState 事件。一旦事件触发(例如触发浏览器的前进后端按钮,或者在控制台输入 history,go,back,forward 赋值),就改变 routerView 的内容。
  • 我们通过 a 标签的 href 属性来改变 URL 的 path 值。这里需要注意的就是,当改变 path 值时,默认会触发页面的跳转,所以需要拦截 `` 标签点击事件的默认行为,这样就阻止了 a 标签自动跳转的行为, 点击时使用 pushState 修改 URL 并更新手动 UI,从而实现点击链接更新 URL 和 UI 的效果。
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/430389
推荐阅读
相关标签
  

闽ICP备14008679号