1.vue-router是什么憔四?
它是一個(gè)vue.js下的路由組件。
2.路由是什么般眉?
router加矛,即“路由”。路由是一個(gè)網(wǎng)絡(luò)工程里面的術(shù)語(yǔ)煤篙。James F.Kurose,Keith W.Ross著.陳鳴譯.《計(jì)算機(jī)網(wǎng)絡(luò)》中有講到
路由(routing)是指分組從源到目的地時(shí),決定端到端路徑的網(wǎng)絡(luò)范圍的進(jìn)程
在WEB開(kāi)發(fā)的世界里面毁腿,路由其實(shí)指的就是控制我們?cè)跒g覽器中輸入的URL應(yīng)該走入哪個(gè)頁(yè)面中的一個(gè)組件辑奈。
3.為什么需要路由苛茂?
在最原始的ASP,以及傳統(tǒng)的 開(kāi)發(fā)中鸠窗,我們?cè)跒g覽器路徑中輸入U(xiǎn)RL妓羊,位于服務(wù)器上的WEB服務(wù)器程序(比如說(shuō)Apache httpd)則會(huì)自動(dòng)更加這URL,找到WEB目錄下對(duì)應(yīng)的文件稍计,通過(guò)一些解析器將服務(wù)端腳本執(zhí)行之后返回的HTML內(nèi)容發(fā)回給瀏覽器躁绸,瀏覽器將收到的HTML渲染出來(lái)。這時(shí)WEB服務(wù)器程序(比如說(shuō)Apache httpd)自己就完成了這個(gè)路由功能臣嚣。
比如說(shuō)wordpress的后臺(tái)就是
http://www.changwei.me/wp-admin/post-new.php
直接請(qǐng)求對(duì)應(yīng)的php腳本净刮,該腳本執(zhí)行之后返回HTML給瀏覽器渲染。
但是現(xiàn)在越來(lái)越流行框架開(kāi)發(fā)了硅则,很多PHP項(xiàng)目都是用框架開(kāi)發(fā)的淹父,框架都遵循單一入口原則,也就是在WEB目錄下只有一個(gè)index.php文件和一些靜態(tài)資源文件怎虫,其他所有業(yè)務(wù)邏輯以及框架本身的代碼都寫(xiě)在WEB目錄外面的各種文件中暑认,所有入站請(qǐng)求都到達(dá)入口文件,入口文件再通過(guò)請(qǐng)求的各種參數(shù)來(lái)判斷應(yīng)該是將請(qǐng)求分發(fā)給WEB目錄外的哪個(gè)文件(控制器)執(zhí)行大审。我們?nèi)绻行夷軌蛘业揭恍┦褂梅浅@系腜HP框架開(kāi)發(fā)的網(wǎng)站蘸际,觀察他們的站內(nèi)連接,各種URL上面有可能會(huì)像這種樣子
http://xxx.com/index.php?module=home&controller=passport&action=login
等等徒扶,這就是該框架通過(guò)入口文件接受module粮彤,controller,action等參數(shù)來(lái)判斷究竟應(yīng)該把該請(qǐng)求分發(fā)給哪個(gè)模塊酷愧,哪個(gè)控制器驾诈,哪個(gè)操作去處理。這樣就可以十分神奇的實(shí)現(xiàn)只有一個(gè)文件就處理千千萬(wàn)萬(wàn)邏輯的方法溶浴。
到了現(xiàn)在WEB2.0時(shí)代乍迄,信息分享是很多用戶(hù)上網(wǎng)的主要操作,如果你的URL足夠簡(jiǎn)短美觀士败,那么用戶(hù)只需要簡(jiǎn)單的輸入U(xiǎn)RL就可以訪(fǎng)問(wèn)對(duì)應(yīng)的網(wǎng)頁(yè)闯两,而不用輸入一堆module,controller谅将,action之類(lèi)的非IT行業(yè)的用戶(hù)看起來(lái)不明不白的單詞漾狼。同時(shí)也為了SEO(搜索引擎優(yōu)化)和URL美觀,因此路由便誕生了饥臂。
路由可以進(jìn)一步將類(lèi)似于
http://xxx.com/index.php?module=home&controller=passport&action=login
這樣的URL簡(jiǎn)寫(xiě)成
http://xxx.com/login
這樣看起來(lái)是不是美觀了很多逊躁。
4.Apache自帶URL重寫(xiě)可以達(dá)到上述目的,為什么還需要路由隅熙?
?
如果你會(huì)問(wèn)出這個(gè)問(wèn)題稽煤,你一定還沒(méi)有體驗(yàn)過(guò)PHP的Laravel框架核芽。
我們看一看Laravel在輸出hello world的時(shí)候,用xphrof做性能測(cè)試的結(jié)果酵熙,發(fā)現(xiàn)路由相關(guān)的操作占據(jù)了大量執(zhí)行時(shí)間轧简,從中也可以側(cè)面看出Laravel中路由的功能強(qiáng)大。
前面說(shuō)了這么多匾二,還是沒(méi)講到路由究竟好在哪哮独?為什么不用各種WEB服務(wù)器自帶的URL重寫(xiě)功能?
首先URL重寫(xiě)只是單純的正則表達(dá)式匹配請(qǐng)求URL察藐,然后將請(qǐng)求轉(zhuǎn)發(fā)到真正的URL路徑上執(zhí)行皮璧,這里從高內(nèi)聚低耦合的角度來(lái)看,URL重寫(xiě)將一個(gè)WEB程序的業(yè)務(wù)邏輯分散到了WEB服務(wù)器程序和WEB程序兩個(gè)地方转培。并且我們從Apache服務(wù)器程序換到nginx上還需要修改配置文件恶导,移植性降低了。另外我們有的時(shí)候需要對(duì)一組URL進(jìn)行一些特殊的操作浸须,比如說(shuō)所有后臺(tái)操作請(qǐng)求都必須驗(yàn)證登錄操作惨寿,在傳統(tǒng)的開(kāi)發(fā)中,要么在每一個(gè)后臺(tái)操作的腳本(控制器)中寫(xiě)一個(gè)驗(yàn)證操作删窒,更加高級(jí)一點(diǎn)的會(huì)include一個(gè)驗(yàn)證腳本裂垦,但是怎么看還是不夠優(yōu)雅。現(xiàn)在有路由了肌索,可以將一組和后臺(tái)操作有關(guān)的URL都劃分到一個(gè)分組中蕉拢,然后綁定中間件(和java中的過(guò)濾器,攔截器很像)
5.vue-router在前端開(kāi)發(fā)中能帶來(lái)什么好處诚亚?
前面講了這么多關(guān)于路由的好處晕换,其實(shí)都指的是后端路由。也就是前后端不分離的項(xiàng)目中的路由≌咀冢現(xiàn)在我們是前后端分離項(xiàng)目中闸准,路由有什么用,能帶來(lái)什么好處呢梢灭?
我們先看看知乎客戶(hù)端
??這是知乎客戶(hù)端的兩個(gè)頁(yè)面夷家。
我們先來(lái)看看這個(gè)需求:
有一天產(chǎn)品經(jīng)理說(shuō)需要開(kāi)發(fā)一個(gè)像知乎一樣的SPA,要求底部有一些按鈕固定不動(dòng)的底部導(dǎo)航欄敏释,頂部也有一個(gè)帶有返回按鈕的導(dǎo)航欄固定不動(dòng)库快,點(diǎn)擊底部導(dǎo)航欄之后,中間部分的頁(yè)面應(yīng)該跳轉(zhuǎn)到對(duì)應(yīng)功能頁(yè)面钥顽,點(diǎn)擊頂部的返回按鈕之后义屏,應(yīng)該返回到之前的頁(yè)面。
如果是傳統(tǒng)開(kāi)發(fā),你肯定第一想到的是使用css的display進(jìn)行切換顯示不同的vue組件(components)實(shí)現(xiàn)湿蛔。
但是我們看到知乎底部的“我的”按鈕存在一個(gè)邏輯膀曾,如果用戶(hù)沒(méi)有登錄,那么他會(huì)跳轉(zhuǎn)到登錄頁(yè)面阳啥,如果已經(jīng)登錄則顯示對(duì)應(yīng)頁(yè)面。如果使用傳統(tǒng)開(kāi)發(fā)财喳,那么就會(huì)顯得很不優(yōu)雅察迟。
另外還要考慮一個(gè)情況,就是一般訪(fǎng)問(wèn)SPA的用戶(hù)都是移動(dòng)端耳高,移動(dòng)端最需要考慮的就是加載速度扎瓶,并且不能耗費(fèi)用戶(hù)過(guò)多流量。那么就需要讓用戶(hù)點(diǎn)擊這個(gè)按鈕之后再加載這個(gè)組件的相關(guān)代碼泌枪,以及該組件需要請(qǐng)求的數(shù)據(jù)概荷,最后在渲染頁(yè)面。
最后就是URL要美觀漂亮碌燕,并且URL可以動(dòng)態(tài)接受參數(shù)误证,比如說(shuō)網(wǎng)易云音樂(lè)這個(gè)非常典型的SPA項(xiàng)目便使用了后端路由并且可以接受參數(shù)
http://music.163.com/#/my/m/music/playlist?id=121597667
要滿(mǎn)足這些需求的話(huà),在vue.js下使用vue-router是最合適不過(guò)的了修壕。
6.vue-router都提供了什么愈捅?
1.前端路由(編程式導(dǎo)航 · GitBook):讓頁(yè)面中的部分內(nèi)容可以無(wú)刷新的跳轉(zhuǎn),就像原生APP一樣慈鸠。
2.懶加載(懶加載 · GitBook):結(jié)合異步組件以及在組建的created鉤子上觸發(fā)獲取數(shù)據(jù)的ajax請(qǐng)求(數(shù)據(jù)獲取 · GitBook)可以最大化的降低加載時(shí)間蓝谨,減少流量消耗。
3.重定向(重定向 和 別名 · GitBook):可以實(shí)現(xiàn)某些需要根據(jù)特定邏輯改變頁(yè)面原本路由的需求青团,比如說(shuō)未登錄狀態(tài)下訪(fǎng)問(wèn)“個(gè)人信息”時(shí)應(yīng)該重定向到登錄頁(yè)面譬巫。
4.美化URL(HTML5 History 模式):還記得前面網(wǎng)易云音樂(lè)的URL嗎?
http://music.163.com/#/my/m/music/playlist?id=121597667
網(wǎng)易云音樂(lè)網(wǎng)頁(yè)版的URL里面幾乎都帶有一個(gè)#號(hào)督笆,大家可能會(huì)疑惑芦昔,#號(hào)是URL的hash部分,并不會(huì)傳遞到服務(wù)端胖腾,那么#號(hào)起什么作用呢烟零?其實(shí)前端路由器就是通過(guò)URL的hash部分來(lái)像傳統(tǒng)的后端路由器一樣判斷某些請(qǐng)求需要交給哪個(gè)前端組件處理。
但是大家都會(huì)覺(jué)得URL里面帶一個(gè)#號(hào)太丑了咸作,要是能像傳統(tǒng)WEB應(yīng)用一樣的URL多好锨阿。這個(gè)時(shí)候vue-router提供的“HTML5 History 模式”就“完美”解決了這個(gè)問(wèn)題。
為什么前面的完美要加上引號(hào)呢记罚?
請(qǐng)參考官方文檔:
不過(guò)這種模式要玩好墅诡,還需要后臺(tái)配置支持。因?yàn)槲覀兊膽?yīng)用是個(gè)單頁(yè)客戶(hù)端應(yīng)用,如果后臺(tái)沒(méi)有正確的配置末早,當(dāng)用戶(hù)在瀏覽器直接訪(fǎng)問(wèn) http://oursite.com/user/id 就會(huì)返回 404烟馅,這就不好看了。
所以呢然磷,你要在服務(wù)端增加一個(gè)覆蓋所有情況的候選資源:如果 URL 匹配不到任何靜態(tài)資源郑趁,則應(yīng)該返回同一個(gè)index.html 頁(yè)面,這個(gè)頁(yè)面就是你 app 依賴(lài)的頁(yè)面姿搜。
這里還要引出另一個(gè)話(huà)題寡润,就是為什么前端路由的時(shí)候需要改變URL呢?前面提到了WEB2.0時(shí)代是一個(gè)信息分享的時(shí)代舅柜,如果用戶(hù)切換到了另一個(gè)頁(yè)面梭纹,但是URL仍然顯示的是index.html,那么用戶(hù)想要分享這個(gè)頁(yè)面給他的朋友致份,他的朋友訪(fǎng)問(wèn)到的則只是這個(gè)SPA的首頁(yè)变抽,并不是這個(gè)分享的用戶(hù)本身希望他朋友看到的頁(yè)面。因此前端路由在改變頁(yè)面的時(shí)候必須讓URL跟著一起變氮块。這樣同時(shí)也近似完美地解決了歷史上ajax導(dǎo)致瀏覽器返回前進(jìn)按鈕失效的問(wèn)題绍载。
5.前置操作,中間件雇锡,過(guò)濾器逛钻,攔截器(導(dǎo)航鉤子 · GitBook)
在后端路由中都有前置操作,中間件锰提,過(guò)濾器曙痘,攔截器等概念。前端路由也可以有的立肘,vue-router本身較為完美的支持了這些功能边坤,讓你做前端SPA開(kāi)發(fā)就像后端開(kāi)發(fā)一樣。在第三點(diǎn)提到的用戶(hù)未登錄重定向的判斷邏輯就可以寫(xiě)在這里谅年。
6.路由元信息(路由元信息 · GitBook):后端路由中可以對(duì)路由規(guī)則進(jìn)行分組茧痒,比如說(shuō)把所有需要登錄才能訪(fǎng)問(wèn)的頁(yè)面劃分為一組。vue-router并沒(méi)有路由規(guī)則分組功能融蹂,但是它提供了路由元信息旺订,可以在元信息中定義一些規(guī)則,在路由鉤子中再去判斷這些規(guī)則超燃,進(jìn)行相應(yīng)的操作区拳。
7.滾動(dòng)位置控制(滾動(dòng)行為 · GitBook):相對(duì)于官方翻譯的滾動(dòng)行為,我更喜歡自己將他翻譯為“滾動(dòng)位置控制”意乓,官方文檔對(duì)于它的作用已經(jīng)講的比較通俗易懂了樱调,大家可以參閱官方文檔學(xué)習(xí)。