Vue开发中,在实现单页面应用(SPA)前端路由时的hash模式和history模式的区别及详细介绍

简介: Vue开发中,在实现单页面应用(SPA)前端路由时的hash模式和history模式的区别及详细介绍
一、前言

单页面应用(SPA)的核心思想之一,就是更新视图而不重新请求页面,简单来说,它在加载页面时,不会加载整个页面,只会更新某个指定的容器中的内容。对于大多数单页面应用,都推荐使用官方支持的vue-router。

在实现单页面前端路由时,提供了两种方式,分别是hash模式和history模式,根据mode参数来决定采用哪一种方式。

const router = new VueRouter({
  routes,
  mode: "history" // 或者 "hash"
})


二、hash模式

http://example.com/#/home

Hash模式是Vue.js中默认的URL管理模式。在Hash模式下,URL中的#符号用于标识页面状态的变化。当页面中的路由发生改变时,Vue.js会使用Hash模式来更新URL,并在页面中渲染相应的组件。

  • Hash模式是通过监听hashChange事件来实现的,前端js把当前hash地址对应的组件渲染到浏览器中。
  • 在地址栏URL上有#号。
  • 通常用于单页面应用(SPA),支持页面内的导航,不会刷新页面,也不会影响服务器。
  • Hash出现在URL中,但不包括在http请求中,对后端没有影响。
  • 在进行URL跳转时,如果只改变hash,不会重新加载页面。
hashchange 事件:

当hash值改变时会触发这个事件,通过 location.hash 获取到最新的 hash 值

注意:

  • hash 值的变化不会导致浏览器像服务器发送请求
  • location.hash可以获取hash值
  • hashchange是hash值发生改变的调用的函数

语法:

window.onhashchange = function () {
  console.log(location.hash);
};

// 或

window.addEventListener('hashchange', ()=>{
    console.log(location.hash);
});


三、history模式
http://example.com/home

History模式是另一种URL管理模式,它使用HTML5的History API来实现URL的变化和页面的刷新。在History模式下,URL中的#符号被移除,取而代之的是通过History API来管理页面的状态。


History模式的优点在于它能够实现平滑的页面过渡,提高用户体验。同时,由于URL中不包含#符号,因此也适用于搜索引擎优化。然而,History模式需要在服务器端进行额外的配置,以确保能够正确地处理不同的URL路径请求。

  • History模式是通过调用history.pushState方法(或者replaceState)并且监听popstate事件来实现的。history.pushState会追加历史记录,并更换地址栏地址信息,但是页面不会刷新。
  • 需要服务器端做额外的配置,否则可能会出现刷新页面时的404错误。
  • 在进行URL跳转时,即使只改变hash,也需要重新加载页面(如果当前页面不是SPA)。
  • 支持浏览器的前进、后退功能。
方法:
1、history.go():

通过当前页面的相对位置从浏览器历史记录(会话记录)异步加载页面。

参数:

  • 参数为 -1 的时候为上一页,
  • 参数为 1 的时候为下一页。
  • 当你指定了一个越界值,例如:当会话历史记录中没有之前访问的页面时,则传参的值为 -1,那么这个方法没有任何效果也不会报错。
  • 调用没有参数的 go() 方法或者参数值为 0 时,重新载入当前页面。
  • Internet Explorer 允许你指定一个字符串,而不是整数,以转到历史记录列表中的特定 URL。
2、history.back():

此异步方法转到浏览器会话历史的上一页,与用户单击浏览器的 Back 按钮的行为相同。等价于 history.go(-1)。

调用此方法回到会话历史的第一页之前没有效果并且不会引发异常。


3、history.forward():

此异步方法转到浏览器会话历史的下一页,与用户单击浏览器的 Forward 按钮的行为相同。等价于 history.go(1)。


调用此方法超越浏览器历史记录中最新的页面没有效果并且不会引发异常。


4、History.replaceState()

替换当前页在历史记录中的信息

语法:

history.replaceState(stateObj, title[, url])

参数:


stateObj:状态对象是一个 JavaScript 对象,它与传递给 replaceState 方法的历史记录实体相关联。


title:大部分浏览器忽略这个参数, 将来可能有用。在此处传递空字符串应该可以防止将来对方法的更改。或者,你可以为该状态传递简短标题。


url:可选,历史记录实体的 URL. 新的 URL 跟当前的 URL 必须是同源; 否则 replaceState 抛出一个异常。

5、History.pushState()

向历史记录中追加一条记录

语法:

pushState(stateObj, title, url)

参数:

  • stateObj:一个用于表示历史记录状态的JavaScript对象。这个对象的内容会被添加到浏览器的历史堆栈中。这个参数是可选的。
  • title:为新的历史记录条目提供标题。这个参数通常可以设置为null,因为大多数浏览器在显示历史记录列表时并不使用这个标题。
  • url:可选,要添加到历史记录中的新URL。这个 URL 必须与当前页面处于同一个域中,否则浏览器可能会阻止这个操作。


优势:


  • pushState()设置的新的url可以是于当前url同源的任意url,而hash只可修改#后面的部分,因此只能设置与当亲url同文档的url。


  • pushState()设置的新的url可以与当前url一摸一样,这样也会把记录添加到栈中;而hash设置的新值必须与原来的不一样才会触发动作将记录添加到栈中。
  • pushState()通过stateObject参数可以添加任意类型的数据到记录中;而hash只可添加短字符串。


当你在SPA中使用history.pushState()或者history.replaceState()时,你可能会希望更改浏览器的URL,但是不刷新页面。这可以让你的SPA具有更好的用户体验,因为用户可以点击浏览器的后退和前进按钮来导航,而不需要在你的应用中进行额外的点击。

popState 事件

每当同一个文档的浏览历史(即history)出现变化时,就会触发popState事件。


注意:


  • 仅仅调用pushState方法或replaceState方法,并不会触发该事件,只有用户点击浏览器后退和前进按钮时,或者使用js调用back、forward、go方法时才会触发。
  • 该事件只针对同一个文档,如果浏览历史的切换,导致加载不同的文档,该事件不会被触发。
  • 页面第一次加载的时候,浏览器不会触发popState事件。

语法:

window.onpopstate = function (event) {
  console.log('location: ' + document.location);
  console.log('state: ' +JSON.stringify(event.state));
};

// 或

window.addEventListener('popstate', function(event) {
  console.log('location: ' + document.location);
  console.log('state: ' + JSON.stringify(event.state));
});


四、nginx配置

hash模式下,仅hash符号#之前的内容会被包含在请求中,比如http://www.example.com/home 因此对于后端来说,即使没有做到对路由的全覆盖,也不会返回404错误;

history模式下,前端的url必须和实际后端发起请求的url一致,如http://example.com/about/id 。如果后端缺少对/about/id 的路由处理,将返回404错误。


在Vue.js中,可以使用vue-router库来实现Hash模式和History模式。通过配置vue-router的mode属性,可以选择使用Hash模式或History模式。需要注意的是,项目部署生产后,hash 模式能够正常使用,而 history 模式访问不到资源。hash 的改变不会发生请求,因此不影响服务器端,所以 nginx 不会拦截,而 history 模式则需要设置可访问的配置。


比如http://www.example.com/home 如果不进行配置,那么 nginx 默认会去找服务器目录下的 home 文件,而我们想要的效果则是依旧寻找 index 文件,home 则交给前端去处理,nginx 使用 try_files 配置即可实现该效果。

location / { 
 root /www/wwwroot; 
 index index.html; 
 try_files $uri $uri/ /index.html; 
}
五、原生 Node.js配置
const http = require('http')
const fs = require('fs')
const httpPort = 80

http.createServer((req, res) => {
  fs.readFile('index.html', 'utf-8', (err, content) => {
    if (err) {
      console.log('We cannot open "index.html" file.')
    }

    res.writeHead(200, {
      'Content-Type': 'text/html; charset=utf-8'
    })

    res.end(content)
  })
}).listen(httpPort, () => {
  console.log('Server listening on: http://localhost:%s', httpPort)
})


六、注意

给个警告,因为这么做以后,你的服务器就不再返回 404 错误页面,因为对于所有路径都会返回 index.html 文件。为了避免这种情况,你应该在 Vue 应用里面覆盖所有的路由情况,然后再给出一个 404 页面。

const router = new VueRouter({
  mode: 'history',
  routes: [
    { path: '*', component: NotFoundComponent }
  ]
})

或者,如果你使用 Node.js 服务器,你可以用服务端路由匹配到来的 URL,并在没有匹配到路由的时候返回 404,以实现回退。

更多详情请查阅 Vue 服务端渲染文档


七、如何选择合适的路由模式

使用 Hash 模式:

  • 如果你的项目不需要考虑兼容性问题,或者需要在旧版浏览器中支持路由功能。
  • 如果你希望简化部署过程,只需将静态文件部署到服务器即可。

使用 History 模式:

  • 如果你希望 URL 更加美观、简洁,不希望在 URL 中出现 # 符号。
  • 如果你可以进行服务器配置,确保在直接访问 URL 时返回正确的页面。
  • 如果你的项目不需要考虑旧版浏览器的兼容性问题。
目录
相关文章
|
2月前
|
前端开发 算法 Java
【CSS】前端三大件之一,如何学好?从基本用法开始吧!(六):全方面分析css的Flex布局,从纵、横两个坐标开始进行居中、两端等元素分布模式;刨析元素间隔、排序模式等
Flex 布局 布局的传统解决方案,基于盒状模型,依赖 display 属性 + position属性 + float属性。它对于那些特殊布局非常不方便,比如,垂直居中就不容易实现。 2009年,W3C 提出了一种新的方案----Flex 布局,可以简便、完整、响应式地实现各种页面布局。目前,它已经得到了所有浏览器的支持,这意味着,现在就能很安全地使用这项功能。 一、Flex 布局是什么? Flex 是 Flexible Box 的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性。
257 0
|
4月前
|
JSON 监控 前端开发
AMIS:百度开源的前端低代码神器,18.4k star 背后的开发效率提升利器
AMIS(前端低代码框架)是百度开源的低代码前端框架,基于纯 JSON 配置即可生成完整后台页面,包括表单、表格、图表、CRUD 列表,支持可视化拖拽编辑。,星标数已达 18.4k,百度内部已沉淀超过 5 万个页面,广泛应用于审核系统、数据管理后台、模型监控等落地场景
876 0
|
3月前
|
人工智能 前端开发 JavaScript
前端工程化演进之路:从手工作坊到AI驱动的智能化开发
前端工程化演进之路:从手工作坊到AI驱动的智能化开发
614 18
前端工程化演进之路:从手工作坊到AI驱动的智能化开发
|
9月前
|
JSON 自然语言处理 前端开发
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
493 72
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
|
7月前
|
存储 消息中间件 前端开发
PHP后端与uni-app前端协同的校园圈子系统:校园社交场景的跨端开发实践
校园圈子系统校园论坛小程序采用uni-app前端框架,支持多端运行,结合PHP后端(如ThinkPHP/Laravel),实现用户认证、社交关系管理、动态发布与实时聊天功能。前端通过组件化开发和uni.request与后端交互,后端提供RESTful API处理业务逻辑并存储数据于MySQL。同时引入Redis缓存热点数据,RabbitMQ处理异步任务,优化系统性能。核心功能包括JWT身份验证、好友系统、WebSocket实时聊天及活动管理,确保高效稳定的用户体验。
444 4
PHP后端与uni-app前端协同的校园圈子系统:校园社交场景的跨端开发实践
|
8月前
|
监控 前端开发 小程序
陪练,代练,护航,代打小程序源码/前端UNIAPP-VUE2.0开发 后端Thinkphp6管理/具备家政服务的综合型平台
这款APP通过技术创新,将代练、家政、娱乐社交等场景融合,打造“全能型生活服务生态圈”。以代练为切入点,提供模块化代码支持快速搭建平台,结合智能匹配与技能审核机制,拓展家政服务和商业管理功能。技术架构具备高安全性和扩展性,支持多业务复用,如押金冻结、录屏监控等功能跨领域应用。商业模式多元,包括交易抽成、增值服务及广告联名,同时设计跨领域积分体系提升用户粘性,实现生态共生与B端赋能。
798 12
|
存储 人工智能 前端开发
前端大模型应用笔记(三):Vue3+Antdv+transformers+本地模型实现浏览器端侧增强搜索
本文介绍了一个纯前端实现的增强列表搜索应用,通过使用Transformer模型,实现了更智能的搜索功能,如使用“番茄”可以搜索到“西红柿”。项目基于Vue3和Ant Design Vue,使用了Xenova的bge-base-zh-v1.5模型。文章详细介绍了从环境搭建、数据准备到具体实现的全过程,并展示了实际效果和待改进点。
1042 14
|
JavaScript 前端开发 程序员
前端学习笔记——node.js
前端学习笔记——node.js
341 0
|
人工智能 自然语言处理 运维
前端大模型应用笔记(一):两个指令反过来说大模型就理解不了啦?或许该让第三者插足啦 -通过引入中间LLM预处理用户输入以提高多任务处理能力
本文探讨了在多任务处理场景下,自然语言指令解析的困境及解决方案。通过增加一个LLM解析层,将复杂的指令拆解为多个明确的步骤,明确操作类型与对象识别,处理任务依赖关系,并将自然语言转化为具体的工具命令,从而提高指令解析的准确性和执行效率。
469 6
|
SpringCloudAlibaba JavaScript 前端开发
谷粒商城笔记+踩坑(2)——分布式组件、前端基础,nacos+feign+gateway+ES6+vue脚手架
分布式组件、nacos注册配置中心、openfegin远程调用、网关gateway、ES6脚本语言规范、vue、elementUI
谷粒商城笔记+踩坑(2)——分布式组件、前端基础,nacos+feign+gateway+ES6+vue脚手架

热门文章

最新文章

  • 1
    前端如何存储数据:Cookie、LocalStorage 与 SessionStorage 全面解析
  • 2
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(五):背景属性;float浮动和position定位;详细分析相对、绝对、固定三种定位方式;使用浮动并清除浮动副作用
  • 3
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(六):全方面分析css的Flex布局,从纵、横两个坐标开始进行居中、两端等元素分布模式;刨析元素间隔、排序模式等
  • 4
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(一):CSS发展史;CSS样式表的引入;CSS选择器使用,附带案例介绍
  • 5
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(八):学习transition过渡属性;本文学习property模拟、duration过渡时间指定、delay时间延迟 等多个参数
  • 6
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(九):强势分析Animation动画各类参数;从播放时间、播放方式、播放次数、播放方向、播放状态等多个方面,完全了解CSS3 Animation
  • 7
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(二):CSS伪类:UI伪类、结构化伪类;通过伪类获得子元素的第n个元素;创建一个伪元素展示在页面中;获得最后一个元素;处理聚焦元素的样式
  • 8
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(四):元素盒子模型;详细分析边框属性、盒子外边距
  • 9
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(七):学习ransform属性;本文学习 rotate旋转、scale缩放、skew扭曲、tanslate移动、matrix矩阵 多个参数
  • 10
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(三):元素继承关系、层叠样式规则、字体属性、文本属性;针对字体和文本作样式修改
  • 1
    前端如何存储数据:Cookie、LocalStorage 与 SessionStorage 全面解析
    533
  • 2
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(九):强势分析Animation动画各类参数;从播放时间、播放方式、播放次数、播放方向、播放状态等多个方面,完全了解CSS3 Animation
    205
  • 3
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(八):学习transition过渡属性;本文学习property模拟、duration过渡时间指定、delay时间延迟 等多个参数
    207
  • 4
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(七):学习ransform属性;本文学习 rotate旋转、scale缩放、skew扭曲、tanslate移动、matrix矩阵 多个参数
    150
  • 5
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(六):全方面分析css的Flex布局,从纵、横两个坐标开始进行居中、两端等元素分布模式;刨析元素间隔、排序模式等
    257
  • 6
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(五):背景属性;float浮动和position定位;详细分析相对、绝对、固定三种定位方式;使用浮动并清除浮动副作用
    372
  • 7
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(四):元素盒子模型;详细分析边框属性、盒子外边距
    164
  • 8
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(三):元素继承关系、层叠样式规则、字体属性、文本属性;针对字体和文本作样式修改
    103
  • 9
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(二):CSS伪类:UI伪类、结构化伪类;通过伪类获得子元素的第n个元素;创建一个伪元素展示在页面中;获得最后一个元素;处理聚焦元素的样式
    175
  • 10
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(一):CSS发展史;CSS样式表的引入;CSS选择器使用,附带案例介绍
    239