文章目录
前端路由模式主要指的是在单页面应用(SPA)中,通过前端技术实现页面路由控制,而不是通过传统的页面跳转(即刷新页面)来实现。这种模式允许应用在不重新加载整个页面的情况下,通过更改URL来呈现不同的内容或视图。
Hash 模式
- 特点:
Hash
模式通过在URL
中添加#
号(也称为锚点)和锚点值(hash值)来实现路由。当hash值发生变化时,页面不会重新加载,而是会触发hashchange
事件,从而允许前端JavaScript捕获到这个变化并据此更新页面内容。
Hash 模式的特点
- 兼容性好:支持所有现代浏览器,包括不支持HTML5 History API的旧版浏览器。
- 简单配置:在 Vue 路由中,默认使用 Hash 模式,不需要额外的配置。
- 易于部署:由于使用了 hash,URL 发生变化时不会触发页面刷新,hash 模式不会向后端发送 http 请求,所有的 hash 值操作都与后端无关,因此部署时只需将静态文件部署到服务器即可。
- 缺点:URL中带有#号,不够美观,且在某些情况下可能会与服务器端的锚点功能产生冲突。
hashchange 事件
当 URL 的片段标识符(hash 值)更改时,将触发 hashchange
事件 (跟在#符号后面的 URL 部分,包括#符号)。
- 使用
addEventListener
监听hashchange
事件:
window.addEventListener('hashchange', function() {
console.log('hash值被修改了')
}, false);
- 使用
onhashchange
事件处理程序
function locationHashChanged() {
if (location.hash === '#/about') {
console.log("欢迎进入about页面");
}
}
window.onhashchange = locationHashChanged;
修改 hash 值会优先触发 popstate
事件,然后再触发 hashchange
事件
window.addEventListener('hashchange', function () {
console.log('hashchage 事件被触发了');
});
// hash值的改变也会触发 window.onpopstate事件,onpopstate事件在 history模式中再做介绍
window.addEventListener("popstate", () => {
console.log("popstate 事件被触发了");
})
History 模式
- 特点:
History
模式利用HTML5
的History API
(特别是pushState
和replaceState
方法)来实现路由。它允许开发者在不刷新页面的情况下,改变浏览器的URL地址,并添加新的历史记录条目。与hash模式不同,History模式下的URL不会包含#
号,看起来更加美观。 - 优点:URL更加美观,符合传统URL结构。支持更多的URL操作,如设置状态对象等。
- 缺点:需要后端服务器的配合,以确保在URL直接访问时能够返回正确的页面。否则,当用户直接访问某个路由地址时,服务器可能会返回404错误。
History API
onpopstate 事件
window.onpopstate
事件是用来监听浏览历史记录变化的。
调用 history.pushState()
或者 history.replaceState()
不会触发 popstate
事件。popstate
事件只会在浏览器某些行为下触发,比如点击前进、后退按钮(或者在 JavaScript 中调用 history.back()
、history.forward()
、 history.go()
方法)。即,在同一文档的两个历史记录条目之间导航会触发该事件。
- 使用
addEventListener
监听 popstate 事件:
window.addEventListener('popstate', function(event) {
console.log(event);
}, false);
- 使用
onpopstate
事件处理程序
function historyStateChanged(event) {
console.log(event);
}
window.onpopstate= historyStateChanged;
解决history模式下页面刷新404问题
在 history
下,你可以自由的修改 path,但刷新页面时,如果服务器中没有相应的响应或者资源,则会出现404页面,因为刷新页面会发送 http 请求。也就是说,使用 history 路由模式,需要通过服务端来允许地址可访问,后端也必须配置了当前资源路径地址才行。
如果后台部署使用了 nginx
,可以对 nginx
进行如下配置来解决页面刷新问题(摘录):
server {
listen 8080;
server_name localhost;
location / {
root 'E:\dist';
index /index.html;
try_files $uri $uri/ /index.html;
}
}
如何选择合适的路由模式
使用 Hash
模式:
- 如果你的项目需要考虑兼容性问题,或者需要在旧版浏览器中支持路由功能。
- 如果你希望简化部署过程,只需将静态文件部署到服务器即可。
使用 History
模式:
- 如果你希望 URL 更加美观、简洁,不希望在 URL 中出现
#
符号。 - 如果你可以进行服务器配置,确保在直接访问 URL 时返回正确的页面。
- 如果你的项目不需要考虑旧版浏览器的兼容性问题。
在 Vue 项目中,可以通过在路由配置中设置 mode
属性来切换路由模式:
const router = new VueRouter({
mode: 'history', // 或者 'hash'
routes: [...]
});
在vue-router4中使用history
属性来切换路由模式
const router = createRouter({
history: createWebHistory(), // createWebHistory()
routes: constantRoutes,
scrollBehavior(to, from, savedPosition) {
if (savedPosition) {
return savedPosition
} else {
return { top: 0 }
}
},
});
前端路由模式的实现原理
- Hash模式:通过监听
hashchange
事件来实现路由的跳转和匹配。当URL的hash
值发生变化时,会触发hashchange
事件,前端JavaScript可以捕获到这个事件并据此更新页面内容。 - History模式:利用
HTML5
的History API
(pushState
和replaceState
方法)来修改浏览器的URL地址,并添加新的历史记录条目。同时,通过监听popstate
事件来捕获用户的导航行为(如点击前进、后退按钮或使用history.back()等方法),并据此更新页面内容。
额外拓展:Abstract模式
- 特点:
Abstract
模式是一种不依赖于浏览器环境的路由模式,主要用于非浏览器环境(如Node.js
服务器渲染)或在不支持HTML5 History API的旧版浏览器中。在这种模式下,路由的跳转和匹配完全由前端JavaScript控制,而不依赖于浏览器的URL或历史记录。 - 优点:可以在不支持HTML5 History API的环境中实现路由功能。
- 缺点:由于不依赖于浏览器的URL或历史记录,因此无法利用浏览器的历史记录功能进行页面导航。