目录
一、介绍
VueRouter它是Vue官方的一个路由管理器,相比较于Vue来说其实要更好理解一点,至于什么是VueRouter以及如何使用官方已经介绍的非常详细了,这里不多做介绍。
以下提供参考链接:
下面将实现一个简单的VueRouter的功能,如不想看前置知识可以直接跳到最后的代码实现部分。
二、前置知识
1、Hash模式与History模式
Hash模式与History模式是vue-router的两种路由模式,二者在表现形式和原理上存在区别
1.1 表现形式的区别
比如下面两个url地址:
Hash:https://api.aibianxian.net/igameh5/#/detail/213?token=123,链接中带有#号
History: https://api.aibianxian.net/igameh5/detail/213/123
1.2 原理区别
Hash:基于锚点,锚点的值(#后面)作为路由地址,当地址发生变化后,触发onhashchange事件,然后根据路径决定页面呈现的内容。
History:基于HTML5中的HistoryAPI
- 通过history.pushState() / history.replaceState() 改变地址栏
- 监听popstate事件
- 根据当前路由地址找到对应组件重新渲染
pushState与push方法的区别是:调用push的时候路径会发生变化,会向服务器发送请求,调用pushState的时候,不会向服务器发送请求,只会改变地址栏中的地址,并且将地址记录到历史记录中,可以实现客户端路由
1.3 History模式的使用说明
- History需要服务器的支持
- 单页应用中,服务端不存在某一个地址,会返回404页面
- 在服务端应该除了静态资源外都返回单页应用的index.html
1.4 手写Hash模式
实现原理:通过监听——window.onhashchange
<!-- 说明:为了篇幅更简短一点,只贴上了内容相关代码,多余的标签已去除 -->
<h1>hash模式前端路由</h1>
<a href="#/index">主页</a> 
<a href="#/list">列表页</a> 
<button id="btn1">手动修改 hash进入用户中心页</button>
<div id="app"></div>
<script>
var routers = [
{
path: '/index', component: '<p>首页</p>' },
{
path: '/list', component: '<p>列表页</p>' },
{
path: '/user', component: '<p>用户中心页</p>' },
]
var routerView = document.getElementById('app')
// hash 变化,包括:
// a. JS 修改 url
// b. 手动修改 url 的 hash
// c. 会导致浏览器前进、后退
window.onhashchange = (event) => {
console.log('old url', event.oldURL)
console.log('new url', event.newURL)
console.log('获取hash值:', location.hash)
for(let i = 0;i < routers.length;i++){
if('#'+routers[i].path == location.hash) {
routerView.innerHTML = routers[i].component
}
}
}
// 页面初次加载,获取 hash
document.addEventListener('DOMContentLoaded', () => {
console.log('hash:', location.hash)
})
// JS 手动修改 url
document.getElementById('btn1').addEventListener('click', () => {
location.href = '#/user'
})
</script>
1.5 手写History模式
原理:通过history.pushState()方法【改变网址,不会刷新页面】和window.onpopstate事件监听
类似API:history.replaceState(data, title, targetURL),与pushState不同,会直接替换掉当前url,而不会在history中留下记录
注:需要后端配合支持,使浏览器无论访问什么url,最终都到index.html页面(路由全部由前端实现)
<!-- 说明:为了篇幅更简短一点,只贴上了内容相关代码,多余的标签已去除 -->
<h1>history模式</h1>
<!-- <a href="/index">主页</a> <a href="/list">列表页</a> -->
<button>主页</button> 
<button>列表页</button> 
<button>用户中心页</button> 
<div id="app"></div>
<script