您好,登錄后才能下訂單哦!
vue-router
分為 hash
和 history
模式,前者為其默認模式,url的表現形式為 http://yoursite.com#home
,比較難看。后者的url表現形式為 http://yoursite.com/home
,比較美觀。
但如果要使用 history
模式,我們需要在后端進行額外配置。本文將討論如何配置以及為什么要這樣配置。
history模式的配置方法
我們來看看官方文檔是教我們怎么配置的:HTML5 History 模式。
首先要將 mode
設置為 history
:
const router = new VueRouter({ mode: 'history', routes: [...] })
然后設置后端(這里采用的nginx):
location / { try_files $uri $uri/ /index.html; }
然后就......沒了!顯然官方的教程講的比較簡略,并且我們參照這個教程實際上還是會遇到一些問題。
history模式的配置實踐及原理
強烈建議:閱讀這部分之前,先看一下nginx的這部分文檔和 這部分文檔。
既然官方文檔教我們這樣做了,我們就按照它說的來實踐一下。
只配置前端的情況
首先,我們將 mode
設置為 history
,但不配置后端。然后,假如我們的路由是長這個樣子的:
const routes = [ {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
,靜態服務器會去目標目錄下尋找 home
文件,目標目錄下有這個文件嗎?沒有!所以自然就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_files file ... uri;
然后看一下官方文檔對它的介紹:
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.
大意就是它會按照 try_files
后面的參數依次去匹配 root
中對應的文件或文件夾。如果匹配到的是一個文件,那么將返回這個文件;如果匹配到的是一個文件夾,那么將返回這個文件夾中 index
指令指定的文件。最后一個 uri
參數將作為前面沒有匹配到的fallback。(注意 try_files
指令至少需要兩個參數)
拿我自己的網站舉個例子:
location / { root /data/www/rf-blog-web; index index.html; try_files $uri $uri/ /index.html; }
$uri
是nginx中的變量,比如我訪問的網址是 http://localhost:8080/home
,那么它就代表的 /home
。
在 rf-blog-web
這個目錄中,沒有子目錄,只有一個 index.html
和一些壓縮后的名稱是hash值的.js文件。當我們請求 http://localhost:8080/home
這個地址時,首先查找有無 home
這個文件,沒有;再查找有無 home
目錄,也沒有。所以最終會定位到第三個參數從而返回 index.html
,按照這個規則,所有路由里的url路徑最后都會定位到 index.html
。 vue-router
再獲取參數進行前端頁面的變換,至此,我們已經可以通過 http://localhost:8080/home
這個地址進行成功地訪問了。
而 $uri
這個參數的作用其實是匹配那些.js文件用的,而 $uri/
在這個例子中并沒有多大用,實際上是可以去掉的。
history
模式下可能會遇到的問題及解決方案
在將我的項目(在路由中用了懶加載)改為 history
模式的過程中,有時候發現會出現chunk加載出錯的情況,打開chrome的network發現那個chunk加載404了,是因為請求的url中多了一層路徑。我在這里發現了解決方案。
LinusBorg說,因為在 history
模式中切換路由時,我們是真正改變了頁面的url路徑,所以webpack的runtime會認為它位于 example.com/some/path
。如果 publicPath
是設置的相對路徑,那么webpack加載chunk時可能會變成 example.com/some/path/static/js/3.js
這樣的路徑,然而chunk的真正路徑是 example.com/static/js/3.js
,所以我們需要將 publicPath
設置為絕對路徑( publicPath: '/'
)來解決這個問題。
總結
以上所述是小編給大家介紹的Vue Router history模式的配置方法及其原理,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對億速云網站的支持!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。