Evan's blog Evan's blog
首页
关于
  • 分类
  • 标签
  • 归档
  • H5&CSS3
  • JS
  • TS
  • Node
  • Webpack
  • Vue2
  • Vue3
  • 微信小程序
  • Andorid
  • Flutter
推荐
GitHub (opens new window)

conanan

真相只有一个
首页
关于
  • 分类
  • 标签
  • 归档
  • H5&CSS3
  • JS
  • TS
  • Node
  • Webpack
  • Vue2
  • Vue3
  • 微信小程序
  • Andorid
  • Flutter
推荐
GitHub (opens new window)
  • 基础

  • 组件

  • 动画

  • Composition Api

  • 高级语法

  • Vue源码

  • VueCLI&Vite

  • VueRouter

    • 路由
      • 路由简介
      • 历史 🔥
      • URL 的 hash & HTML5 的 history 🔥
        • hash—URL
        • history—HTML5
    • VueRouter
  • Vuex

  • 项目

  • Vue3.x
  • VueRouter
xugaoyi
2022-02-08
目录

路由

# 路由

# 路由简介

  • 路由就是通过互联的网络把信息从源地址传送到目的地的活动,网络工程术语
  • 路由提供了两种机制:路由和传送
    • 路由是决定数据包从来源到目的地的路径
    • 转送就是将数据转移
  • 路由表
    • 路由表本质就是一个映射表,决定了数据包的指向

# 历史 🔥

  1. 后端渲染,服务端渲染(后端路由)阶段:前端请求一个 URL 后,由例如 Java 如 SpringMVC 中 @RequestMapping 来映射到 Java 代码中,并通过 Servlet 和 JSP 技术编写 HTML 页面(JS+CSS)并填充数据,最后返回给前端完整的 HTML,前端直接渲染展示即可。这种由后端处理 URL 和页面映射关系的称为后端路由。

  2. 前后端分离阶段(Gmail 的 Ajax 大量使用) :前端请求一个 URL 后,可能先从静态资源服务器获取一套 HTML+CSS+JS(服务器中有多套),之后再由 JS 发送 Ajax 请求到后端,由后端返回如 JSON 数据交给前端,前端使用 JS 进行数据填充,渲染 DOM。每次 URL 改变都会请求后端服务器拿静态资源和数据。

  3. 单页面富应用(SPA 页面),前后端分离加上前端路由阶段: 前端第一次请求 URL 后,会从如静态资源服务器获取一套完整的 HTML+CSS+JS(只有一个 HTML,其他 JS 或 CSS 可能会懒加载),之后的 URL 改变不会向后端服务器发送请求,页面不进行整体刷新,而是由其不同的 URL 页面自己发送 Ajax 请求获取数据并由 JS 进行数据填充,渲染 DOM。这种由前端处理 URL 和页面的映射关系称为前端路由。

    那么如何在 URL 改变后页面还不进行整体刷新呢?且看下面介绍。

# URL 的 hash & HTML5 的 history 🔥

提示

Vue CLI 初始化项目时推荐选择 history 模式。URL 看起来更友好,没有#这玩意

# hash—URL

URL 的 hash 是改变锚点#,其本质上改变的是 window.location.hash 属性,不是 href 属性

location.hash = '/user/10000'
http://localhost:8082/#/user/10000

location.hash = '/role/1'
http://localhost:8082/#/role/1
1
2
3
4
5

原理

<!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="#/home">home</a>
    <a href="#/about">about</a>

    <div class="content">Default</div>
  </div>

  <script>
    const contentEl = document.querySelector('.content');
    window.addEventListener("hashchange", () => {
      switch(location.hash) {
        case "#/home":
          contentEl.innerHTML = "Home";
          break;
        case "#/about":
          contentEl.innerHTML = "About";
          break;
        default:
          contentEl.innerHTML = "Default";
      }
    })
  </script>

</body>
</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
31
32
33
34
35

# history—HTML5

HTML5 的 history。是一个栈结构

history.pushState('','','/user/100001')
http://localhost:8082/user/100001

history.pushState('','','/role/1')
http://localhost:8082/role/1

history.back()
http://localhost:8082/user/100001

history.forward()
http://localhost:8082/role/1

history.replaceState('','','/permission/100')
http://localhost:8082/permission/100
# 此时将上面的 http://localhost:8082/role/1 替换掉了,之后无法 back 回去,只能 back 到 http://localhost:8082/user/100001

# go 可以更灵活控制,相比 back,forward
history.go(-1)
history.go(1)
history.go(-2)
history.go(2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

Vue Router 就是将组件和 URL 映射

原理

<!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="/home">home</a>
      <a href="/about">about</a>

      <div class="content">Default</div>
    </div>

    <script>
      const contentEl = document.querySelector('.content')

      const changeContent = () => {
        console.log('-----')
        switch (location.pathname) {
          case '/home':
            contentEl.innerHTML = 'Home'
            break
          case '/about':
            contentEl.innerHTML = 'About'
            break
          default:
            contentEl.innerHTML = 'Default'
        }
      }

      const aEls = document.getElementsByTagName('a')
      for (let aEl of aEls) {
        aEl.addEventListener('click', (e) => {
          // 取消a标签的默认行为
          e.preventDefault()

          const href = aEl.getAttribute('href')
          // 压栈操作,可back
          // history.pushState({}, "", href);
          // 替换操作,无法back
          history.replaceState({}, '', href)

          changeContent()
        })
      }

      window.addEventListener('popstate', changeContent)
    </script>
  </body>
</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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
编辑 (opens new window)
上次更新: 2022/03/23, 17:55:39
Vite
VueRouter

← Vite VueRouter→

最近更新
01
重点
04-12
02
搭建项目
04-04
03
TS补充
03-30
更多文章>
Theme by Vdoing | Copyright © 2019-2022 conanan | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式