今天工作时候遇到了路由问题,挣扎了一早上时间,于是决定研究路由,不破不立。
首先植入一个概念,vue-router是前端路由,前端路由不是vue-router。
所以,什么是前端路由?
前端路由是服务器用来描述页面路径的,也就是你地址栏的里url和文件的关系,也就是映射关系,更加程序化的来描述,就是对象里key和value的关系。
用vue router来举列子。你的地址里path名为home ,你的component就得引用 home.vue
{
path: '/home',
name: 'home',
component: () => import(/* webpackChunkName: "LSD.bighome" */ '../views/home.vue'),
},
路由会做什么?
大致有下面的三个场景。
1.浏览器地址变化时,刷新页面(组件替换或更新)
2.点击浏览器后退和更新,网页内容也变化
3.刷新浏览器,浏览器加载当前的url对应的内容
hash和history 模式区别小览
hash: 通过hashchange 事件监听hash值的变化,值变了,网页内容改变
history :利用history API实现url地址改变,网页内容改变;
认识hash
- hash指的是地址中#号以及后面的字符,也称为散列值。hash也称作锚点,本身是用来做页面跳转定位的。如http://127.0.0.1:5500/hash.html#niubi,这里的
#niubi
就是hash; - 散列值是不会随请求发送到服务器端的,所以改变hash,不会重新加载页面;
- 监听 window 的 hashchange 事件,当散列值改变时,可以通过 location.hash 来获取和设置hash值;
hash模式值散列值进行了变化,真正的路径并没有变,hash 变化时,页面并不会刷新,
只是因为了监听了hashchange的事件,对页面进行了替换。而内容替换这种行为完全由前端控制,因此这种模式使用这种模式的应用也被称为 SPA 应用。
大家观察,vue router的默认模式。就是hash模式。
大家可以用下面的代码去体验hash
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>实现hash</title>
</head>
<body>
<h3>Old Hash: <span id="oldhash"></span></h3>
<h3>new Hash: <span id="newhash"></span></h3>
<button id="btn">Goto gjh</button>
<script>
const btn = document.getElementById('btn')
// 给按钮绑定事件
btn.addEventListener('click', () => {
location.href = '/#/gjh-home'
})
// hash 监听
window.addEventListener('hashchange', (hashevent) => {
const oldhash = document.getElementById('oldhash')
const newhash = document.getElementById('newhash')
// 将新、旧路径赋值到页面对应位置
oldhash.innerText = hashevent.oldURL
newhash.innerText = hashevent.newURL
console.log(hashevent)
})
// hash 监听
// window.onhashchange = (hashevent) => {
// const oldhash = document.getElementById('oldhash')
// const newhash = document.getElementById('newhash')
// // 将新、旧路径赋值到页面对应位置
// oldhash.innerText = hashevent.oldURL
// newhash.innerText = hashevent.newURL
// console.log(hashevent)
// }
</script>
</body>
</html>
认识history
history 和hash最大区别就是,保存了当前窗口访问过的所有页面网址,你可以用history.length 来获取当前的窗口一共访问了几个页面。
也就说,在点击前进和后退按钮时,就是在已经访问过的页面里面去找,因此不会刷新页面。
当改变时 也只是改变页面的路径。
而 history 模式是通过模拟路径变化来切换路由。
我在下图里共添加了15个路径 用history.length就可以访问历史保存页面的数量
这时我们点击后退按钮回到以前访问过的页面时,页面通常是从浏览器缓存之中加载,而不是重新要求服务器发送新的网页。
体验history
History.pushState() 该方法用于在历史中添加一条记录。pushState()方法不会触发页面刷新,只是导致 History 对象发生变化,地址栏会有变化。
popstat() 每当 history 对象出现变化时,就会触发 popstate 事件。
可以用下面的代码 去体验下区别
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>体验history</title>
</head>
<body>
<h3>new path: <span id="newpath"></span></h3>
<button id="btn">Goto gjh</button>
<script>
const btn = document.getElementById('btn')
const newpath = document.getElementById('newpath')
let num= 0
btn.addEventListener('click', () => {
const state = {name: 'gjh'}
// 不会触发 onpopstate 钩子
history.pushState(state, '','gjh'+ (num++))
// ============= 路由切换逻辑 =============== //
newpath.innerText = location.pathname
})
// 监听 path 变化,浏览器前进、后退触发
window.onpopstate = (event) => {
console.log(event)
newpath.innerText = location.pathname
}
</script>
</body>
</html>
但是history 致命的缺点就是当改变页面地址后,强制刷新浏览器时,(如果后端没有做准备的话)会报错,因为刷新是拿当前地址去请求服务器的,如果服务器中没有相应的响应,会出现 404 页面。
hash和history 模式区别大览
hash | history |
能够兼容到IE8 | 能兼容到IE10 |
实际的url之前使用哈希字符,这部分url不会发送到服务器,不需要在服务器层面上进行任何处理 | 每访问一个页面都需要服务器进行路由匹配生成 html 文件再发送响应给浏览器,消耗服务器大量资源 |
刷新不会存在 404 问题 | 浏览器直接访问嵌套路由时,会报 404 问题。 |
不需要服务器任何配置 | 需要在服务器配置一个回调路由 |
有 # 号 | 无#号 |
推荐hash的理由
不需要服务端的配置,它就是通过散列值 就是#号后面path 变化了,进行内容替换
更不需要向网络发起任何的请求
vue-router 默认使用的就是hash
hash弊端
hash 不利于 SEO(搜索引擎优化)。
白屏时间问题。浏览器需要等待 JavaScript 文件加载完成之后渲染 HTML 文档内容,用户等待时间稍长。