Vue Router 是 Vue.js 官方提供的路由管理器,用于构建单页面应用(SPA)。它与 Vue.js 深度集成,提供了一种声明式的方式来导航和渲染组件,使得在不同的路由间切换变得简单且高效。Vue Router 支持多种特性,包括嵌套路由、导航守卫、过渡动画、懒加载等。
createWebHashHistory
vs createWebHistory
createWebHashHistory
和 createWebHistory
是 Vue Router 中用于配置不同路由模式的工厂函数。它们都是 Vue Router v4 版本引入的。不过他们之间的区别不是特别的大,我们可以来对比看看。
createWebHashHistory
createWebHashHistory
是 Vue Router 中用于创建使用哈希模式的路由器的工厂函数。哈希模式利用 URL 的哈希部分(即 #
符号后面的部分)来记录路由信息。当用户在应用中导航时,浏览器的 URL 会改变,但页面不会重新加载,因为浏览器只认为 URL 的哈希部分发生了变化。
优点:
- 兼容性好: 所有浏览器都支持哈希变化,因此哈希模式可以在较旧的浏览器中工作。
- 无需服务器配置: 由于 URL 的哈希部分不会被服务器端解析,所以不需要对服务器做任何特殊配置。
缺点:
- URL 不美观: URL 中包含
#
可能会让 URL 看起来不那么好看或者说清晰。
createWebHistory
createWebHistory
用于创建使用 HTML5 History API 的路由器。History 模式下,URL 看起来就像传统的多页面应用那样,没有 #
字符。这意味着 URL 更加简洁和直观。
优点:
- URL 清晰: URL 没有
#
,看起来更像常规的网页链接。 - SEO(搜索引擎优化) 友好: 对搜索引擎优化更有利,因为搜索引擎爬虫更容易理解不带
#
的 URL。
缺点:
- 服务器配置: 需要服务器端配置,以便在请求任何路由时都能返回同一个 index.html 文件,否则可能会出现 404 错误。
- 兼容性问题: 虽然大多数现代浏览器都支持 HTML5 History API,但对于一些老旧浏览器可能不适用。
对比
-
URL的美观性:
createWebHashHistory()
: URL中包含#
,可能看起来不够专业或整洁,但不需要服务器端做任何额外配置。createWebHistory()
: URL中不包含#
,更加美观,更接近传统的多页面应用的URL结构,对SEO友好。
-
服务器配置:
createWebHashHistory()
: 不需要服务器端配置,因为URL中的#
部分不会被服务器解析,所有的请求都会被解析为同一个入口文件(如index.html
)。createWebHistory()
: 需要服务器端配置,以便所有非主入口的URL请求都能够被重定向回主入口文件,避免404错误。
-
兼容性:
createWebHashHistory()
: 具有很好的兼容性,几乎所有浏览器都支持URL的哈希变更。createWebHistory()
: 虽然现代浏览器广泛支持HTML5的History API,但对于一些旧版浏览器,可能不支持此API。
-
性能和用户体验:
createWebHashHistory()
: 在某些情况下,页面加载和状态转换可能更快,因为浏览器不需要发送额外的请求来确认URL的变更。createWebHistory()
: 用户体验可能更好,因为URL的变化更加直观,且在多窗口或标签页中更容易区分不同的应用状态。
选择建议
选择哪种模式取决于你的应用需求和服务器配置。如果服务器已经正确配置来处理 HTML5 History API,那么使用 createWebHistory()
会得到更干净的 URL;如果服务器配置是个问题或者你想简化开发流程,那么使用 createWebHashHistory()
可能更合适。除去这些的话,他们俩也就是有无#
的区别
那么#
是个什么玩意
这就要说说锚点与锚链接了
在 HTML 中,锚点和锚链接是用于页面内导航的机制。锚点通过 id
或 name
属性定义,而锚链接则使用 href
属性指向某个锚点,格式为 #
加上锚点的 id
或 name
。
示例:
运行结果:
在 Vue Router 的哈希模式下,锚点链接的工作方式与纯 HTML 中相同。当点击这个链接时,浏览器会跳转到 URL + #yilou 这个锚链接, 并在浏览器的地址栏显示#yilou,但是页面不会刷新,只会展示这个锚点的地方。而 Vue Router 的哈希模式就是运用了来自锚链接 的原生能力,点击链接时,url会发生改变 #hash, 用于实现单页应用的路由功能,不会刷新当前的页面,相应的组件显示到router-view位置就好咯,就实现了单页应用的要求。
手写一个Hash Router
-
首先,我们要先创建一个导航栏, 定义导航栏中的链接,点击链接会改变 URL 的哈希部分。在Vue中我们是使用
<router-view></router-view>
定义一个路由入口,来显示路由组件的内容。这里我们用原生JS写的话,就用一个id="container"
来设置一个容器,用于显示根据哈希值加载的不同内容。<nav id="nav"> <ul> <li><a href="#/page1">page1</a></li> <li><a href="#/page2">page2</a></li> <li><a href="#/page3">page3</a></li> </ul> </nav> <div id="container"> //在这里显示根据哈希值加载的不同内容 </div>
-
既然要在
id="container"
这个容器里操作,就得先拿到这个容器。 -
还需要监听
hashchange
事件,拿到点击链接改变的 URL 的哈希部分 -
然后每当点击链接的时候,往该容器里面添加html代码片段,去展示
-
那我们就要将链接的哈希部分与html代码片段一一对应。
-
这样的话,我们就创建一个对象,去存放这些item。
-
当用户点击链接时,将拿到的哈希部分与对象中的key对比,相同的话就输出展示这个html片段。
-
那我们需要先将现有的路径存放在对象中,并且设置好首页,当没有点击时先展示首页给用户看。
-
要是用户自己随意输入了一个路径的哈希部分,而我们并没有,那代码应该不执行。
-
考虑到复用性,我们直接将
HashRouter
封装一下。//封装一个hashRouter class HashRouter{ constructor(){ this.routes={}; //page => component 对象 window.addEventListener("hashchange",this.load.bind(this),false); } register(hash,callback=function(){}){ this.routes[hash]=callback; } registerIndex(callback=function(){}){ this.routes["index"]=callback; } load(){ let hash = location.hash.slice(1)//去掉#号 然后就是路由 let handler if(!hash){ // 去到首页 handler = this.routes["index"] }else{ // 去相应的页面 handler = this.routes[hash] } handler && handler.call(this) // 确保handler存在才执行后面那个 } } let router =new HashRouter() let container =document.getElementById("container") router.registerIndex(()=>container.innerHTML='我是首页') router.register('/page1',()=>container.innerHTML='我是page1') router.register('/page2',function(){ container.innerHTML='我是page2' }) router.register('/page3',()=>container.innerHTML='我是page3') router.load() //一开始初始化页面时,先调用一次,展现首页
-
来看看效果怎么样
总结
通过本文,我们不仅了解了Vue Router中createWebHashHistory
和createWebHistory
两种模式的特点与应用场景,还亲自动手实现了一个简易的Hash Router。无论是对于前端开发者还是对单页面应用架构感兴趣的读者,相信都能从中获得宝贵的见解。
选择合适的路由模式对于构建流畅、用户友好的单页面应用至关重要。在实际项目中,应当根据项目的具体需求、目标用户群体以及服务器配置情况综合考量,做出最合理的选择。
如果你对本文有任何疑问或见解,欢迎留言讨论。期待在前端开发的学习旅程中,与你一起加油!