【JS】VueRouter——原理实现(八.1)
写在开头
左思右想还是决定再加一章,这章主要介绍路由的原理实现,并且会使用代码模拟VueRouter的原理。我学习前端的感觉是,框架有很多,会用就可以。但设计的思想却值得我们去研究,因为这才是框架的灵魂,以及真正的智慧所在。其实在使用框架的时候我们不难发现,有些命令或者方法我们用的多了甚至能猜出它的设计思想以及实现原理。所以熟练使用一个框架或许并不难,但如果不能懂得它设计的初衷以及其中的奥妙,就总是会觉得缺少一些什么。废话少说,进入正题。
1.模式
先看看这个:https://blog.csdn.net/fifteen...
引用其中的一段话,关于hash和history的区别(划重点,要考!):
VueRouter拥有两种模式,那就是我们熟悉的hash和history,所以在设计时也要将这两种不同的模式都考虑进来。代码如下:
hash:
<body><!-- a标签 = router-link -->
<a href="#/">首页</a>
<a href="#/about">关于</a>
<!-- div = router-view -->
<div id="view"></div>
<script>
const vw = document.getElementById("view")
window.addEventListener("hashchange", () => {
if (location.hash == "#/") {
vw.innerHTML = "我是首页"
} else if (location.hash == "#/about") {
vw.innerHTML = "我是关于"
}
})
</script>
</body>
看看效果:
那么问题来了,router-link的tag属性可以改变显示的标签。也就是说如果不是默认的a标签该怎么做呢?继续改进,代码如下:
<body><!-- 任意标签 = router-link -->
<span onclick="changeHash('#/')">首页</span>
<span onclick="changeHash('#/about')">关于</span>
<!-- div = router-view -->
<div id="view"></div>
<script>
function changeHash (path) {
location.hash = path
}
window.addEventListener("hashchange", () => {
if (location.hash == "#/") {
view.innerHTML = "我是首页"
} else if (location.hash == "#/about") {
view.innerHTML = "我是关于"
}
})
</script>
</body>
看看效果:
解决方案就是我们可以通过为任意标签添加点击事件,并在点击时传入对应的hash值,然后在点击事件处理函数中改变地址栏的hash值。
可以看到,使用a标签和div模拟的vueRouter,似乎还像那么回事儿。所以hash模式下路由的原理也显而易见,说白了就是:
history:
<body><!-- 任意标签 = router-link -->
<span onclick="changeHash('/')">首页</span>
<span onclick="changeHash('/about')">关于</span>
<!-- div = router-view -->
<div id="view"></div>
<script>
function changeHash (path) {
history.pushState(null, null, path)
if (location.pathname == "/") {
view.innerHTML = "首页是我"
} else if (location.pathname == "/about") {
view.innerHTML = "关于是我"
}
}
</script>
</body>
看看效果:
可以看到浏览器的回退和前进并没有效果,这也是与hash模式不同的地方。改进:
<body><!-- 任意标签 = router-link -->
<span onclick="changeHash('/')">首页</span>
<span onclick="changeHash('/about')">关于</span>
<!-- div = router-view -->
<div id="view"></div>
<script>
function changeHash (path) {
history.pushState(null, null, path)
if (location.pathname == "/") {
view.innerHTML = "首页是我"
} else if (location.pathname == "/about") {
view.innerHTML = "关于是我"
}
}
window.addEventListener("popstate", () => {
if (location.pathname == "/") {
view.innerHTML = "首页是我"
} else if (location.pathname == "/about") {
view.innerHTML = "关于是我"
}
})
</script>
</body>
看看变化:
那么其实history模式下的路由原理其实也可以总结出来了:
使用history.pushState API来切换地址栏的路径,再通过监听popstate事件来操作浏览器的回退和前进按钮。
总结
代码没什么可讲的,着重说说hash和history各自的特点。
1.hash:"#" 可以理解为锚点,它的url会更改、浏览器可以前进和后退、但浏览器不会刷新、并且不会和服务端交流
2.history:无"#" 可以理解为没有锚点,它是规范的url、是能够访问到后台的、需要服务端的同事进行配合
本来想着这一章把原理的内容都写完,但实在是模拟路由的内容太多了,还是放在后面一点一点写完吧。本章已经将路由的原理带出来了,后面的内容会相对初级的实现路由。
Keep foolish, keep hungry.
以上是 【JS】VueRouter——原理实现(八.1) 的全部内容, 来源链接: utcz.com/a/94435.html