美文网首页
vue-router的实现原理

vue-router的实现原理

作者: 未路过 | 来源:发表于2022-10-03 12:18 被阅读0次

URL:协议://主机:端口/路径?查询

URL: scheme://localhost:port/path?query

里面的qurey是type=sell&page=3&...

什么=什么然后再用&连接

1.改变url但是不刷新页面的7种方式

html4

  1. history.go
  2. history.back
  3. history.forward()

html5

  1. pushState(data{}, title'', url)
    ata参数表示再添加记录时传递的数据对象,页面显示的标题,页面跳转地址

  2. popState(data{}, title'', url)

  3. replaceState(data{}, title'', url)

  4. location.href:可以获取到地址栏的信息(当前页面的完整路径)

  5. location.hash来改变href, location.hash="/foo"

2.实现原理

2.1 hash 模式下

1. this.$router.push()

this.$router.push()是由vue-router内部调用HashHistory.push()方法,这个方法本质是直接改变window.location.hash的值来实现的。将新路由添加到浏览器访问历史的栈顶。
window.onHashChange来监听hash值的改变,一旦发生变化就找出此hash值所匹配的组件,
进而将组件渲染到页面中。但是hash模式这种带hash值的url是非常丑的,项目中也很少用hash模式。

 <body>
    <div id="app">
      <a href="#/main">main</a>
      <a href="#/login">login</a>
      <!-- 注意这里href里面只能是#开头,不能/开头 -->
    </div>
    <script>
      console.log(location.hash) //空的字符串
      console.log(location.href) //http://127.0.0.1:5500/src/store/index.html
      location.hash = '/'
      console.log(location.hash) //   #/
      console.log(location.href) //   http://127.0.0.1:5500/src/store/index.html#/
      /* location.hash就是#后面的东西 */
      location.hash = '/foo'
      console.log(location.hash) //   #/foo
      console.log(location.href) //http://127.0.0.1:5500/src/store/index.html#/foo

      /*通过以上的方式是可以通过浏览器的返回,前进按钮来看历史记录的  */
    </script>
  </body>

2. this.$router.replace()

this.$router.replace()是由又vuerouter内部调用HashHistory.replace()方法,这个方法本质是用window.location.replace方法将路由进行替换。

<body>
    <button class="mybutton">button</button>
    <script>
      location.hash = '/foo'
      console.log(location.hash) //   #/foo
      console.log(location.href) //   http://127.0.0.1:5500/demo.html#/foo
      /* location.hash就是#后面的东西,包括# */

      const btn = document.querySelector('.mybutton')

      btn.onclick = function () {
        console.log('btn click')
        location.replace('http://127.0.0.1:5500/demo.html#/bar')
        console.log('replace end')
        console.log(location.hash)
        console.log(location.href)
      }
    </script>
  </body>

进入页面之后,


image.png

这时候第一次打开页面,没有回退和前进按钮有效,
然后我们点击按钮,location.replace当前的路由,从#/foo到#bar


image.png

回退按钮也没有变的有效。

3.实现vue-router的hash模式

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <div id="app">
      <a href="#/main">main</a>
      <a href="#/login">login</a>
      <!-- 注意这里href里面只能是#开头,不能/开头 -->
    </div>
    <div class="content">
      <div class="router-view">router-view</div>
    </div>

    <script>
      const rouerView = document.querySelector(".router-view");
      window.addEventListener("hashchange", () => {
        console.log("hashchange", location.hash);
        switch (location.hash) {
          case "#/main":
            rouerView.innerHTML = "main";
            break;
          case "#/login":
            rouerView.innerHTML = "login";
            break;
          default:
            rouerView.innerHTML = "not found";
        }
      });
    </script>
  </body>
</html>

2. hitory模式

2.1 this.$router.push()

this.$router.push()---》window.history.pushState(stateObject, title, URL)

2.2 this.$router.replace()

this.$router.replace()--->window.history.replaceState(stateObject, title, URL)
不是将新路由添加到浏览器访问历史的栈顶,而是替换掉当前的路由。

2.3 实现vue-router

通过window.onpopstate来监听路由变化,进而匹配不同的组件来渲染出来。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <div id="app">
      <a href="/main">main</a>
      <a href="/login">login</a>
    </div>
    <div class="content">
      <div class="router-view">router-view</div>
    </div>

    <script>
      const rouerView = document.querySelector(".router-view");
      const aEls = document.querySelectorAll("a");
      const historyChange = function () {
        switch (location.pathname) {
          case "/login":
            rouerView.innerHTML = "login";
            break;
          case "/main":
            rouerView.innerHTML = "main";
            break;
          default:
            rouerView.innerHTML = "not found";
        }
      };

      for (const aEl of aEls) {
        aEl.addEventListener("click", (e) => {
          e.preventDefault();
          const href = aEl.getAttribute("href");
          history.pushState({}, "", href);
          historyChange();
        });

        window.addEventListener("popstate", historyChange);
        /* 
点击浏览器的【前进】【后退】按钮,或者调用 history 对象的 back、forward、go 
方法调用过 history 对象的 replaceState 或 pushState 方法
都会满足popstate的触发条件
        */
      }
    </script>
  </body>
</html>

相关文章

  • 手写 Vue Router、手写响应式实现、虚拟 DOM 和 D

    Vue-Router 原理实现 一、Vue-Router 动态路由 二、Vue-Router 嵌套路由 三、Vue...

  • vue总结

    vue路由守卫 vue实现双向绑定原理 Vue生命周期: vue跨域方式 vue-router实现原理 vue-r...

  • 一起学Vue:路由(vue-router)

    前言 学习vue-router就要先了解路由是什么?前端路由的实现原理?vue-router如何使用?等等这些问题...

  • Vue路由 ---- vue-router

    vue-router 中常用的 hash 和 history 路由模式实现原理吗? Two Point!!! sp...

  • 第四天

    1、vue-router实现原理? 1.hash url后面会有#号 通过window.onhashchange...

  • 58转转前端面经

    一面: 自我介绍 vue双向绑定原理,用了js哪些方法实现 vue-router原理 ES6了解哪些 webpac...

  • vue-router实现原理

    1.编写路由,routes;包括路径,及映射组件 2.创建路由实例 mode设置为history表示利用了hist...

  • vue-router实现原理

    随着前端应用的业务功能起来越复杂,用户对于使用体验的要求越来越高,单面(SPA)成为前端应用的主流形式。大型单页应...

  • vue-Router原理实现

    vue-Router有两种模式 Hash 与 History Hash 模式是基于锚点,以及 onhashchan...

  • Vue-Router 原理实现

    使用步骤 1.创建router对象,router/index.js 2.注册router 对象, main.js ...

网友评论

      本文标题:vue-router的实现原理

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