摘要:這段話沒具體應(yīng)用過之后根據(jù)不同的,來執(zhí)行不同的方案構(gòu)造器構(gòu)造器接收個(gè)參數(shù),和是在定義新路由的時(shí)候創(chuàng)建的對象如果沒有傳,則為,這是通過一個(gè)名為的外部工具為加上強(qiáng)類型檢查的功能,不影響編譯和運(yùn)行。
前言
單頁Web應(yīng)用(single page web application,SPA),就是只有一張Web頁面的應(yīng)用,是加載單個(gè)HTML 頁面并在用戶與應(yīng)用程序交互時(shí)動態(tài)更新該頁面的Web應(yīng)用程序。簡單來說就是用戶只需要加載一次頁面就可以不再請求,當(dāng)點(diǎn)擊其他子頁面時(shí)只會有相應(yīng)的URL改變而不會重新加載。
我們可以將實(shí)現(xiàn)路由的過程分為兩部分:
更新URL頁面不刷新
監(jiān)聽URL的變化,執(zhí)行頁面替換邏輯
現(xiàn)在主流有2種實(shí)現(xiàn)方案:
history.pushState等觸發(fā)popstate事件
location.hash的變化觸發(fā)hashchange事件
接下來我們一步一步看Vue-router如何實(shí)現(xiàn)的
Vue-router源碼解剖 構(gòu)造器請各位同學(xué)翻到 src/index.js 第18行
export default class VueRouter { static install: () => void; static version: string; app: any; apps: Array; ready: boolean; readyCbs: Array ; options: RouterOptions; mode: string; history: HashHistory | HTML5History | AbstractHistory; matcher: Matcher; fallback: boolean; beforeHooks: Array; resolveHooks: Array; afterHooks: Array; constructor (options: RouterOptions = {}) { this.app = null this.apps = [] this.options = options this.beforeHooks = [] this.resolveHooks = [] this.afterHooks = [] this.matcher = createMatcher(options.routes || [], this) let mode = options.mode || "hash" this.fallback = mode === "history" && !supportsPushState && options.fallback !== false if (this.fallback) { mode = "hash" } if (!inBrowser) { mode = "abstract" } this.mode = mode switch (mode) { case "history": this.history = new HTML5History(this, options.base) break case "hash": this.history = new HashHistory(this, options.base, this.fallback) break case "abstract": this.history = new AbstractHistory(this, options.base) break default: if (process.env.NODE_ENV !== "production") { assert(false, `invalid mode: ${mode}`) } } }
構(gòu)造器接收一個(gè)options參數(shù)
默認(rèn)mode為 "hash",如果顯示傳入?yún)?shù)mode為"history",則進(jìn)行 是否支持的"history"的判斷
this.fallback = mode === "history" && !supportsPushState && options.fallback !== false
supportsPushState方法 里面 判斷了 是否為瀏覽器環(huán)境且當(dāng)前瀏覽器版本支持history
options.fallback用來控制路由,在設(shè)置了mode為"history"但是當(dāng)前瀏覽器環(huán)境不支持"history"的情況下是否應(yīng)該回調(diào)判斷,并重新設(shè)置mode為"hash"。
設(shè)置fallback為false本質(zhì)上是為了讓"router-link"在IE9上可以完整的頁面刷新,如果是在hash模式下面不支持SSR,設(shè)置為false,會讓那些在ie9服務(wù)端渲染的app更好用。(這段話沒具體應(yīng)用過)
之后根據(jù)不同的mode,來執(zhí)行不同的方案
HTML5History 構(gòu)造器構(gòu)造器接收2個(gè)參數(shù),router和base
router是在定義新路由的時(shí)候創(chuàng)建的對象
base如果沒有傳,則為undefined,
"?"這是通過一個(gè)名為flow的外部工具為javascript加上強(qiáng)類型檢查的功能,不影響編譯和運(yùn)行。直接無視就好。
調(diào)動History的構(gòu)造方法,History為 HTML5History,HashHistory,AbstractHistory的超類
在History的構(gòu)造方法中,
如果base為undefined,查找是否有base的元素,有就賦值,沒有就"/"
之后
const expectScroll = router.options.scrollBehavior const supportsScroll = supportsPushState && expectScroll if (supportsScroll) { setupScroll() }
判斷路由參數(shù),是否控制路由頁面滾動條行為
監(jiān)聽popstate事件,跳轉(zhuǎn)
獲取當(dāng)前l(fā)ocation的值之后,
進(jìn)行路由的更新,比如當(dāng)前的History對應(yīng)哪個(gè)路由
Html5History也添加了go,push,replace等方法用來路由跳轉(zhuǎn),
先保存滾動條狀態(tài),之后可以使用history的自帶方法進(jìn)行地址的改變
更多詳情請見MDN
未完待續(xù)
HashHistory 構(gòu)造器
調(diào)動History的構(gòu)造方法,History為 HTML5History,HashHistory,AbstractHistory的超類
判斷當(dāng)前hash地址
如果開頭不是/#,將當(dāng)前l(fā)ocation按照hash格式化
根據(jù)href獲取當(dāng)前hash,如果沒有匹配到"#"返回空字符串。
初始化地址欄hash后
監(jiān)聽popstate事件,替換路由,控制滾動條行為
導(dǎo)航守衛(wèi)在registerHook將設(shè)置的守衛(wèi)入棧
在每次跳轉(zhuǎn)的時(shí)候,遞歸守衛(wèi)集合,將觸發(fā)的守衛(wèi)進(jìn)行解析和執(zhí)行。
相對于上兩種方法,AbstractHistory看起來要簡單很多,這種模式是用于 Node.js 環(huán)境的,一般場景也就是在做測試的時(shí)候。但是在實(shí)際項(xiàng)目中其實(shí)還可以使用的,利用這種特性還是可以很方便的做很多事情的。(我沒有用過)
因?yàn)椴簧婕昂蜑g覽器地址相關(guān)記錄關(guān)聯(lián)在一起;整體流程依舊和 HashHistory 是一樣的,只是這里通過數(shù)組來模擬瀏覽器歷史記錄堆棧信息。
更新歷史堆棧信息,更新當(dāng)前所處位置
等等,除了不使用瀏覽器的history對象,其他的和html5history模式差不多。
vue-router的源碼剖析到這里就結(jié)束了,大概流程是這個(gè)樣子,得益于開發(fā)人員代碼的簡潔性及可讀性,我們閱讀起來障礙還是沒有那么多,難度也沒有那么大,整體邏輯不復(fù)雜,但是想要把很多不復(fù)雜的細(xì)節(jié),整合到一起,認(rèn)真到細(xì)節(jié),才是程序設(shè)計(jì)的美學(xué)。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/95668.html
摘要:使用值來作路由。原生應(yīng)用本身就是多頁的場景,頁面間狀態(tài)的隔離比共享更重要一些。使用開發(fā)的是原生應(yīng)用,頁面棧的管理使用的也是原生的特性,沒有但是有模塊可以實(shí)現(xiàn)頁面的前進(jìn)和后退等操作。 系列文章的目錄在 ? 這里 (由于 我比較懶 最近一段時(shí)間在忙其他事,系列文章拖了好久終于又更新了。。。) 什么是 vue-router ? vue-router 官方文檔 vue-router 是針對 V...
摘要:所以單頁應(yīng)用的部署,需要將所有的頁面請求都返回,瀏覽器下載了后會自動解析并導(dǎo)航到對應(yīng)頁面。總結(jié)單頁應(yīng)用與以前的常規(guī)多頁面應(yīng)用還是有區(qū)別的,開發(fā)過程與后端解耦了,同時(shí)會出現(xiàn)跨域鑒權(quán)以及應(yīng)用部署的問題。 本文同步發(fā)布于我的個(gè)人博客上 - 單頁應(yīng)用的部署方案 本文主要簡單講一下單頁應(yīng)用的開發(fā)及部署方法,默認(rèn)你懂一些服務(wù)端知識及nginx知識,如果有任何可以在下方評論留言。 單頁應(yīng)用 SPA(...
摘要:后端路由簡介路由這個(gè)概念最先是后端出現(xiàn)的。前端路由模式隨著的流行,異步數(shù)據(jù)請求交互運(yùn)行在不刷新瀏覽器的情況下進(jìn)行。通過這些就能用另一種方式來實(shí)現(xiàn)前端路由了,但原理都是跟實(shí)現(xiàn)相同的。 后端路由簡介 路由這個(gè)概念最先是后端出現(xiàn)的。在以前用模板引擎開發(fā)頁面時(shí),經(jīng)常會看到這樣 http://www.xxx.com/login 大致流程可以看成這樣: 瀏覽器發(fā)出請求 服務(wù)器監(jiān)聽到80端口(或4...
摘要:如果要相應(yīng)狀態(tài)改變,通常最好使用計(jì)算屬性或取而代之。那解決問題的思路便是在改變的情況下,保證頁面的不刷新。后面值的變化,并不會導(dǎo)致瀏覽器向服務(wù)器發(fā)出請求,瀏覽器不發(fā)出請求,也就不會刷新頁面。 1.vue生命周期2.vue 雙向綁定原理3.vue router原理4.vue router動態(tài)路由 1.vue 生命周期鉤子 showImg(https://segmentfault.com/...
摘要:如果要相應(yīng)狀態(tài)改變,通常最好使用計(jì)算屬性或取而代之。那解決問題的思路便是在改變的情況下,保證頁面的不刷新。后面值的變化,并不會導(dǎo)致瀏覽器向服務(wù)器發(fā)出請求,瀏覽器不發(fā)出請求,也就不會刷新頁面。 1.vue生命周期2.vue 雙向綁定原理3.vue router原理4.vue router動態(tài)路由 1.vue 生命周期鉤子 showImg(https://segmentfault.com/...
閱讀 2805·2021-11-22 14:44
閱讀 545·2021-11-22 12:00
閱讀 3686·2019-08-30 15:54
閱讀 1577·2019-08-29 17:15
閱讀 1904·2019-08-29 13:50
閱讀 1113·2019-08-29 13:17
閱讀 3520·2019-08-29 13:05
閱讀 1184·2019-08-29 11:31