原文网址:Vue--Router--路由模式--种类/区别/原理_IT利刃出鞘的博客-CSDN博客
简介
说明
本文介绍Vue Router的三种路由模式,包括原理、优缺点、使用场景。
Router三种路由模式
- hash:使用URL的hash值作为路由。
- Vue的默认路由模式。
- 支持所有浏览器。
- history:使用History API:pushState() 和 replaceState() 方法。
- HTML5之后支持。
- abstract:支持所有 JavaScript 运行环境(包括Node.js 服务器端)
- 如果发现没有浏览器的 API,路由会自动强制进入这个模式。
官网
hash模式
说明
根据MDN:Location 接口的 hash 属性返回一个 USVString,包含URL标识中的 '#' 和 后面URL片段标识符,被称为 hash。
例如:http://www.abc.com/#/article,hash 的值为 #/article。
- 第一个#后的所有字符,都会被浏览器解读为位置标识符,它只用来表示页面位置(一个锚点)。这些字符都不会被发送到服务器端。
- 单单改变#后的部分,浏览器只会滚动到相应位置,不会重新加载网页。
- 每次改变#后的部分,都会在浏览器的访问历史中增加一个记录。见:此文
- window.location.hash 表示 hash 值。此属性可读可写。
- 使用 window.addEventListener("hashchange", fun) 可以监听 hash 的变化
原理
Vue的Router的hash模式的原理是:使用 window.addEventListener("hashchange", fun) 监听 hash 的变化,hash变化之后,根据这个新的hash找到相应的页面,然后更新视图。
优点
- 后端不需要额外配置
- 原因:#及之后的字符不会被发到服务器
- 例如:http://www.abc.com/#/article在Vue Router中有对应的路由,而我直接输入了http://www.abc.com/#/article/id,Vue Router中没有对应路由。
- 此时并不会报错。
- 原因:只有http://www.abc.com会被发送到服务器。
缺点
- 不美观(url中带了个“#”)
history模式
说明
window.history 提供了两类API:
- 跳到某个浏览记录:back(), forward(), go(),
- 添加/修改历史记录:pushState(), replaceState()
这些方法都只修改当前url,不会向后端发起请求。
原理
- Vue监听url改变这个事件:window.addEventListener('popstate', fun);
- Vue在切换页面时,使用pushState(), replaceState()来修改当前的url
- 切换页面之后,popstate事件被触发,调用相应的回调函数更新视图
优点
- 美观(url中不带“#”)
缺点
- 后端需要额外配置
- 原因:当直接访问一个url时会请求后端。例如:刷新页面、直接通过url访问
- 例如:http://www.abc.com/article在Vue Router中有对应的路由,而我直接输入了http://www.abc.com/article/id,Vue Router中没有对应路由。
- 此时会报错:404。
- 原因:后端没有相应的接口。
- 解决方案:
- 后端(Apache 或 Nginx)进行简单的路由配置
- Vue配置路由的 404 页面。例如:
-
const router = new Router({ mode: 'history', routes: [ { path: '*', component: NotFoundComponent } ] })
-
abstract模式
说明
abstract 模式针对的是没有浏览器环境的情况。
比如 Weex 客户端开发,内部是没有浏览器 API 的,那么 Vue-Router 自身会对环境做校验,强制切换到 abstract 模式。
如果在 Vue-Router 的配置项中不写 mode 的值,在浏览器环境下会默认启用 Hash 模式,在移动客户端下使用 abstract 模式。
原理
通过 stack 和 index 2个变量,模拟出浏览器的历史调用记录。
hash和history的区别
项 | hash | history |
是否有“#” | 有 | 无 |
是否设置后端 | 不需要 | 需要 |
设置的URL | 本文档的url。 hash 只可修改 # 后面的部分,因此只能设置与当前 URL 同文档的 URL。 | 任意同源url。 pushState() 设置的新 URL 可以是与当前 URL 同源的任意 URL。 |
是否添加到历史记录 | hash 设置的新值必须与原来不一样才会触发动作将记录添加到栈中。 | pushState() 设置的新 URL 可以与当前 URL 一模一样,这样也会把记录添加到栈中。 |
记录的数据 | 短字符串。 | 任意类型的数据。 pushState() 通过 stateObject 参数可以添加任意类型的数据到记录中 |
是否可设置title | 不能。 | pushState() 可额外设置 title 属性供后续使用。 |
模式的切换
以切换为history模式为例。
vue2.0.x 的写法
// vue2.0.x 写法比较简单
import Router from 'vue-router'
Vue.use(Router)
const router = new Router({
mode: "history",
routes
})
vue3.0x 的写法
// 在最顶部引入createWebHistory
import { createRouter, createWebHistory, } from 'vue-router'
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{ .... }
]
const router = createRouter({
history: createWebHistory(), // 在调用 createWebHistory() 即可
routes
})
使用场景
hash模式
若没特殊需求,用默认的hash模式即可。
history模式
如果想路径中没有#,则选择history模式
abstract模式
如果是非浏览器环境,则用abstract模式。