天天看點

配置方法_Vue Router history模式的配置方法及其原理

作者:ryougifujino 

原文:https://segmentfault.com/a/1190000019391139

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: '/'

)來解決這個問題。

推薦閱讀

  1. Vue scoped與深度選擇器deep的原理
  2. Vue.js 元件複用和擴充之道
  3. 【深入vue】為什麼Vue3.0不再使用defineProperty實作資料監聽?
  4. 帶你五步學會Vue SSR
  5. Vue3 新增API

❤️愛心三連擊

1.看到這裡了就點個在看支援下吧,你的「點贊,在看」是我創作的動力。

2.關注公衆号

前端名獅

,回複「1」加入前端交流群,一起學習進步!

3.也可添加微信【qq1248351595】,一起成長。

配置方法_Vue Router history模式的配置方法及其原理

“在看轉發”是最大的支援

繼續閱讀