Vue Router history模式的配置方法及其原理
vue-router
分為 hash
和 history
模式,前者為其默認(rèn)模式,url的表現(xiàn)形式為 http://yoursite.com#home
,比較難看。后者的url表現(xiàn)形式為 http://yoursite.com/home
,比較美觀。
但如果要使用 history
模式,我們需要在后端進(jìn)行額外配置。本文將討論如何配置以及為什么要這樣配置。
history模式的配置方法
我們來(lái)看看官方文檔是教我們?cè)趺磁渲玫模篐TML5 History 模式。
首先要將 mode
設(shè)置為 history
:
const router = new VueRouter({ mode: 'history', routes: [...] })
然后設(shè)置后端(這里采用的nginx):
location / { try_files $uri $uri/ /index.html; }
然后就......沒(méi)了!顯然官方的教程講的比較簡(jiǎn)略,并且我們參照這個(gè)教程實(shí)際上還是會(huì)遇到一些問(wèn)題。
history模式的配置實(shí)踐及原理
強(qiáng)烈建議:閱讀這部分之前,先看一下nginx的這部分文檔和 這部分文檔。
既然官方文檔教我們這樣做了,我們就按照它說(shuō)的來(lái)實(shí)踐一下。
只配置前端的情況
首先,我們將 mode
設(shè)置為 history
,但不配置后端。然后,假如我們的路由是長(zhǎng)這個(gè)樣子的:
const routes = [ {path: '/home', component: Home}, {path: '/', redirect: '/home'} ];
我們用nginx部署項(xiàng)目,然后在地址欄輸入 http://localhost:8080
(這里配置的端口是8080),你會(huì)發(fā)現(xiàn)地址欄之后會(huì)變?yōu)?http://localhost:8080/home
,并且 看起來(lái)一切正常, 似乎路由也可以正常切換而不會(huì)發(fā)生其他問(wèn)題(實(shí)際上會(huì)發(fā)生問(wèn)題,后面會(huì)進(jìn)行討論)??雌饋?lái)好像不需要按官網(wǎng)告訴我們的那樣配置后端也能實(shí)現(xiàn) history
模式,但如果你直接在地址欄輸入 http://localhost:8080/home
,你會(huì)發(fā)現(xiàn)你獲得了一個(gè)404頁(yè)面。
那么 http://localhost:8080
為什么可以(部分)正常顯示呢?道理其實(shí)很簡(jiǎn)單,你訪問(wèn) http://localhost:8080
時(shí),靜態(tài)服務(wù)器(這里是nginx)會(huì)默認(rèn)去目標(biāo)目錄(這里為 location
中 root
所指定的目錄)下尋找 index.html
(這是nginx在端口后沒(méi)有額外路徑時(shí)的默認(rèn)行為),目標(biāo)目錄下有這個(gè)文件嗎?有!然后靜態(tài)服務(wù)器返回給你這個(gè)文件,配合 vue-router
進(jìn)行轉(zhuǎn)發(fā),自然可以(部分)正常顯示。
但如果直接訪問(wèn) http://localhost:8080/home
,靜態(tài)服務(wù)器會(huì)去目標(biāo)目錄下尋找 home
文件,目標(biāo)目錄下有這個(gè)文件嗎?沒(méi)有!所以自然就404了。
配置后端
為了達(dá)到直接訪問(wèn) http://localhost:8080/home
也可以成功的目的,我們需要對(duì)后端(這里即nginx)進(jìn)行一些配置。
首先想想,要怎樣才能達(dá)到這個(gè)目的呢?
在傳統(tǒng)的 hash
模式中( http://localhost:8080#home
),即使不需要配置,靜態(tài)服務(wù)器始終會(huì)去尋找 index.html
并返回給我們,然后 vue-router
會(huì)獲取 #
后面的字符作為參數(shù),對(duì)前端頁(yè)面進(jìn)行變換。
類(lèi)比一下,在 history
模式中,我們所想要的情況就是:輸入 http://localhost:8080/home
,但最終返回的也是 index.html
,然后 vue-router
會(huì)獲取 home
作為參數(shù),對(duì)前端頁(yè)面進(jìn)行變換。那么在nginx中,誰(shuí)能做到這件事呢?答案就是 try_files
。
首先看一下try_files的語(yǔ)法: try_files file ... uri;
然后看一下官方文檔對(duì)它的介紹:
Checks the existence of files in the specified order and uses the first found file for request processing; the processing is performed in the current context. The path to a file is constructed from the file parameter according to the root and alias directives. It is possible to check directory's existence by specifying a slash at the end of a name, e.g. “$uri/”. If none of the files were found, an internal redirect to the uri specified in the last parameter is made.
大意就是它會(huì)按照 try_files
后面的參數(shù)依次去匹配 root
中對(duì)應(yīng)的文件或文件夾。如果匹配到的是一個(gè)文件,那么將返回這個(gè)文件;如果匹配到的是一個(gè)文件夾,那么將返回這個(gè)文件夾中 index
指令指定的文件。最后一個(gè) uri
參數(shù)將作為前面沒(méi)有匹配到的fallback。(注意 try_files
指令至少需要兩個(gè)參數(shù))
拿我自己的網(wǎng)站舉個(gè)例子:
location / { root /data/www/rf-blog-web; index index.html; try_files $uri $uri/ /index.html; }
$uri
是nginx中的變量,比如我訪問(wèn)的網(wǎng)址是 http://localhost:8080/home
,那么它就代表的 /home
。
在 rf-blog-web
這個(gè)目錄中,沒(méi)有子目錄,只有一個(gè) index.html
和一些壓縮后的名稱(chēng)是hash值的.js文件。當(dāng)我們請(qǐng)求 http://localhost:8080/home
這個(gè)地址時(shí),首先查找有無(wú) home
這個(gè)文件,沒(méi)有;再查找有無(wú) home
目錄,也沒(méi)有。所以最終會(huì)定位到第三個(gè)參數(shù)從而返回 index.html
,按照這個(gè)規(guī)則,所有路由里的url路徑最后都會(huì)定位到 index.html
。 vue-router
再獲取參數(shù)進(jìn)行前端頁(yè)面的變換,至此,我們已經(jīng)可以通過(guò) http://localhost:8080/home
這個(gè)地址進(jìn)行成功地訪問(wèn)了。
而 $uri
這個(gè)參數(shù)的作用其實(shí)是匹配那些.js文件用的,而 $uri/
在這個(gè)例子中并沒(méi)有多大用,實(shí)際上是可以去掉的。
history
模式下可能會(huì)遇到的問(wèn)題及解決方案
在將我的項(xiàng)目(在路由中用了懶加載)改為 history
模式的過(guò)程中,有時(shí)候發(fā)現(xiàn)會(huì)出現(xiàn)chunk加載出錯(cuò)的情況,打開(kāi)chrome的network發(fā)現(xiàn)那個(gè)chunk加載404了,是因?yàn)檎?qǐng)求的url中多了一層路徑。我在這里發(fā)現(xiàn)了解決方案。
LinusBorg說(shuō),因?yàn)樵?history
模式中切換路由時(shí),我們是真正改變了頁(yè)面的url路徑,所以webpack的runtime會(huì)認(rèn)為它位于 example.com/some/path
。如果 publicPath
是設(shè)置的相對(duì)路徑,那么webpack加載chunk時(shí)可能會(huì)變成 example.com/some/path/static/js/3.js
這樣的路徑,然而chunk的真正路徑是 example.com/static/js/3.js
,所以我們需要將 publicPath
設(shè)置為絕對(duì)路徑( publicPath: '/'
)來(lái)解決這個(gè)問(wèn)題。
總結(jié)
以上所述是小編給大家介紹的Vue Router history模式的配置方法及其原理,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
- vue3配置router路由并實(shí)現(xiàn)頁(yè)面跳轉(zhuǎn)功能
- Vue3路由配置createRouter、createWebHistory、useRouter和useRoute詳解
- Vue3實(shí)戰(zhàn)學(xué)習(xí)配置使用vue?router路由步驟示例
- vue-router如何實(shí)現(xiàn)history模式配置
- Vue-Router的routes配置詳解
- vue-router的使用方法及含參數(shù)的配置方法
- 使用vue-router為每個(gè)路由配置各自的title
- vue router 配置路由的方法
- vue-router+nginx 非根路徑配置方法
- vue中的Router基本配置命令實(shí)例詳解
相關(guān)文章
vue.js前后端數(shù)據(jù)交互之提交數(shù)據(jù)操作詳解
這篇文章主要介紹了vue.js前后端數(shù)據(jù)交互之提交數(shù)據(jù)操作,結(jié)合實(shí)例形式較為詳細(xì)的分析了vue.js前后端數(shù)據(jù)交互相關(guān)的表單結(jié)構(gòu)、約束規(guī)則、數(shù)據(jù)提交等相關(guān)操作技巧與注意事項(xiàng),需要的朋友可以參考下2018-04-04Vue關(guān)閉當(dāng)前彈窗頁(yè)面的兩種方式
這篇文章主要給大家介紹了關(guān)于Vue關(guān)閉當(dāng)前彈窗頁(yè)面的兩種方式,這是最近項(xiàng)目中遇到的一個(gè)需求,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-07-07vscode中eslint插件的配置(prettier配置無(wú)效)
這篇文章主要介紹了vscode中eslint插件的配置(prettier配置無(wú)效),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-09-09詳解Vue 事件驅(qū)動(dòng)和依賴(lài)追蹤
本篇文章主要介紹了詳解Vue 事件驅(qū)動(dòng)和依賴(lài)追蹤 ,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-04-04vue 輸入電話號(hào)碼自動(dòng)按3-4-4分割功能的實(shí)現(xiàn)代碼
這篇文章主要介紹了vue 輸入電話號(hào)碼自動(dòng)按3-4-4分割功能的實(shí)現(xiàn)代碼,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-04-04vue中的echarts實(shí)現(xiàn)寬度自適應(yīng)的解決方案
這篇文章主要介紹了vue中的echarts實(shí)現(xiàn)寬度自適應(yīng),本文給大家分享實(shí)現(xiàn)方案,代碼簡(jiǎn)單易懂,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-09-09vue項(xiàng)目proxyTable配置小結(jié)
本文主要介紹了vue項(xiàng)目proxyTable配置小結(jié),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-04-04vue中的事件觸發(fā)(emit)及監(jiān)聽(tīng)(on)問(wèn)題
這篇文章主要介紹了vue中的事件觸發(fā)(emit)及監(jiān)聽(tīng)(on)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-10-10前端vue3手動(dòng)設(shè)置滾動(dòng)條位置/自動(dòng)定位詳細(xì)代碼
這篇文章主要給大家介紹了關(guān)于前端vue3手動(dòng)設(shè)置滾動(dòng)條位置/自動(dòng)定位的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)學(xué)習(xí)或者使用vue3具有一定的參考解決價(jià)值,需要的朋友可以參考下2024-05-05