当前位置: 首页 > Web前端 > CSS

VueRouter历史模式的配置方法和原理

时间:2023-03-30 16:02:59 CSS

源自我的博客ryogifujino.com,欢迎访问和留言。vue-router分为hash和history模式,前者是它的默认模式,url表示为http://yoursite.com#home,比较丑。后面的url表示为http://yoursite.com/home,比较漂亮。但是如果我们想使用历史模式,我们需要在后端做额外的配置。本文讨论如何以及为何以这种方式配置它。history模式的配置方法看一下官方文档教我们如何配置:HTML5History模式。先设置mode为history:constrouter=newVueRouter({mode:'history',routes:[...]})然后设置backend(这里使用nginx):location/{try_files$uri$uri//index.html;}然后……走了!显然,官方的教程比较简短,我们在参考这个教程的时候,其实也会遇到一些问题。history模式的配置实践和原理强烈推荐:阅读本部分前,先阅读本部分nginx文档和本部分文档。既然官方文档是这么教我们的,那我们就照着说的来练习吧。只配置前端的情况首先,我们将mode设置为history,不配置后端。然后,如果我们的路由是这样的:constroutes=[{path:'/home',component:Home},{path:'/',redirect:'/home'}];我们使用nginx来部署项目,然后在地址栏输入http://localhost:8080(这里配置的端口是8080),你会发现地址栏会变成http://localhost:8080/home,而且一切似乎都很正常,好像路由也可以切换,没有其他问题(其实会出问题,后面再说)。好像官网告诉我们不配置后台也可以实现history模式,但是如果直接在地址栏输入http://localhost:8080/home,你会发现你得到的是404页面。那么为什么http://localhost:8080可以(部分)正常显示呢?原因其实很简单。当你访问http://localhost:8080时,静态服务器(这里是nginx)会默认到目标目录(这里是location中root指定的目录)去搜索index.html(这个是nginx默认的端口之后没有附加路径时的行为),此文件是否在目标目录中?有!然后静态服务器把这个文件返回给你,用vue-router转发,就可以(部分)正常显示了。但是如果直接访问http://localhost:8080/home,静态服务器会去target目录下寻找home文件。target目录下有这个文件吗?不!所以自然是404。配置后端为了达到直接访问http://localhost:8080/home的目的,我们需要在后端做一些配置(这里是nginx)。首先想一想,我们怎样才能达到这个目标呢?在传统的hash模式下(http://localhost:8080#home),即使不需要配置,静态服务器也会一直寻找index.html返回给我们,然后vue-router会获取到之后的字符#作为参数,改造前端页面。以此类推,在history模式下,我们要的是:输入http://localhost:8080/home,但是最后返回的也是index.html,然后vue-router会把home作为参数,执行前面-结束页面转换。那么在nginx中,谁能做到这一点呢?答案是try_files。先看try_files的语法:try_filesfile...uri;然后看看官方文档中对它的介绍:Checkstheexistenceoffilesinthespecifiedorderandusethefirstfoundfileforrequestprocessing;处理在当前上下文中执行。文件的路径是根据root和alias指令从文件参数构造的。可以通过在名称末尾指定斜杠来检查目录是否存在,例如“$uri/”。如果没有找到任何文件,则内部重定向到最后一个参数中指定的uri。大意是会根据try_files后面的参数匹配根目录下对应的文件或文件夹。如果匹配到一个文件,则返回该文件;如果匹配到一个文件夹,则返回该文件夹下index命令指定的文件。最后一个uri参数将用作之前未匹配的回退。(注意try_files命令至少需要两个参数)以我自己的网站为例:location/{root/data/www/rf-blog-web;索引index.html;try_files$uri$uri//index.html;$uri是nginx中的一个变量。比如我访问的URL是http://localhost:8080/home,那么就代表/home。在rf-blog-web目录下,没有子目录,只有一个index.html和一些压缩后名为hash值的.js文件。当我们请求地址http://localhost:8080/home时,首先检查是否有home文件,没有;然后检查是否有主目录,没有。所以最后会定位到第三个参数,返回index.html。根据这个规则,路由中的所有url路径最终都会位于index.html。然后vue-router获取参数对前端页面进行改造。至此,我们可以通过地址http://localhost:8080/home成功访问到。$uri参数的作用其实就是用来匹配那些.js文件的,而$uri/在这个例子中用处不大,其实可以去掉。history模式可能遇到的问题及解决方案在我的项目(在路由中使用懒加载)改成history模式的过程中,有时会发现会出现chunkloading错误。打开chrome的网络,发现Thatchunkloaded404因为请求的url多了一层路径。我在这里找到了解决方案。LinusBorg说因为在history模式下切换路由的时候,我们真的改变了页面的url路径,所以webpackruntime会认为它位于example.com/some/path。如果publicPath是设置的相对路径,那么webpack加载chunk的时候,可能会变成example.com/some/path/static/js/3.js这样的路径,但是chunk的真实路径是example.com/static/js/3.js,所以我们需要设置publicPath为绝对路径(publicPath:'/')来解决这个问题。