摘要:圖在中應(yīng)用三數(shù)據(jù)渲染過程數(shù)據(jù)綁定實(shí)現(xiàn)邏輯本節(jié)正式分析從到數(shù)據(jù)渲染到頁面的過程,在中定義了一個(gè)的構(gòu)造函數(shù)。
一、概述 vue已是目前國內(nèi)前端web端三分天下之一,也是工作中主要技術(shù)棧之一。在日常使用中知其然也好奇著所以然,因此嘗試閱讀vue源碼并進(jìn)行總結(jié)。本文旨在梳理初始化頁面時(shí)data中的數(shù)據(jù)是如何渲染到頁面上的。本文將帶著這個(gè)疑問一點(diǎn)點(diǎn)“追究”vue的"思路"。總體來說vue模版渲染大致流程如圖1所示:
圖1:vue模版渲染流程
從圖中可以看到模版渲染過程經(jīng)歷了數(shù)據(jù)處理(initState)、模版編譯(compileToFunctions)生成渲染函數(shù)(render)、render函數(shù)生成虛擬dom、虛擬dom映射為真實(shí)DOM (patch)掛載到頁面這幾個(gè)過程。上述幾個(gè)函數(shù)在數(shù)據(jù)渲染過程中起到了關(guān)鍵作用。因此本文就從這幾個(gè)函數(shù)出發(fā),深入研究vue數(shù)據(jù)渲染到頁面上的原理。
二、什么是Virtual DOM "); vue利用虛擬DOM技術(shù)來提高頁面渲染和更新的速度。因此在正式分析數(shù)據(jù)渲染過程之前,有必要先了解一下什么是Virtual DOM,以及Virtual DOM的優(yōu)勢。 2.1 virtual dom 產(chǎn)生的原因 Virtual DOM 產(chǎn)生的前提是瀏覽器中的 DOM操作 是很“昂貴"的,為了更直觀的感受,我把一個(gè)簡單的 div 元素的屬性都打印出來,如圖2所示:
圖2:dom元素屬性
可以看到,瀏覽器把 DOM 設(shè)計(jì)的非常復(fù)雜、非常龐大。在瀏覽器當(dāng)中,dom的實(shí)現(xiàn)和ECMAScript的實(shí)現(xiàn)是分離的。因此當(dāng)我們頻繁的去做 DOM 更新,就是頻繁通過js代碼調(diào)用dom的接口,就相當(dāng)于兩個(gè)相互獨(dú)立的模塊發(fā)生了交互。這樣,相比于在同一個(gè)模塊當(dāng)中互相調(diào)用,這種跨模塊的調(diào)用它的性能損耗是非常高的。并且dom操作導(dǎo)致瀏覽器的重繪(repaint)和重排(reflow)會帶來更大的性能損耗。只要在渲染過程中進(jìn)行一次 DOM 更新,整個(gè)渲染流程都會重做一遍。如圖3所示:
圖3:瀏覽器渲染流程
而 Virtual DOM 就是用一個(gè)原生的 JS 對象去描述一個(gè) DOM 節(jié)點(diǎn),所以它比創(chuàng)建一個(gè) DOM 的代價(jià)要小很多。圖4所示為vitrual dom結(jié)構(gòu):
圖4:Virtual DOM實(shí)例
上述的virtual dom最后會生成真實(shí)的dom結(jié)構(gòu)。如圖5所示:
圖5:Virtual DOM映射成真實(shí)dom
在 Vue.js 中,Virtual DOM 是用 VNode 這么一個(gè) Class 去描述, 是對真實(shí) DOM 的一種抽象描述,它的核心定義無非就幾個(gè)關(guān)鍵屬性,標(biāo)簽名、數(shù)據(jù)、子節(jié)點(diǎn)、鍵值等。由于 VNode 只是用來映射到真實(shí) DOM 的渲染,不需要包含操作 DOM 的方法,因此它是非常輕量和簡單的。當(dāng)數(shù)據(jù)發(fā)生改變時(shí)是一次性渲染到頁面,同時(shí)vue內(nèi)部通過diff算法減少頁面的重繪和重排,從而提高了頁面渲染的速度。 2.2 Virtual DOM 主要思想 VirtualDOM的主要思想就是模擬DOM的樹狀結(jié)構(gòu),在內(nèi)存中創(chuàng)建保存映射DOM信息的節(jié)點(diǎn)數(shù)據(jù),在由于交互等因素需要視圖更新時(shí),先通過對節(jié)點(diǎn)數(shù)據(jù)進(jìn)行diff得到差異結(jié)果后,再一次性對DOM進(jìn)行批量更新操作,這就好比在內(nèi)存中創(chuàng)建了一個(gè)平行世界,瀏覽器中DOM樹的每一個(gè)節(jié)點(diǎn)與屬性數(shù)據(jù)都在這個(gè)平行世界中存在著另一個(gè)版本的虛擬DOM樹,所有復(fù)雜曲折的更新邏輯都在平行世界中的VirtualDOM處理完成,只將最終的更新結(jié)果發(fā)送給瀏覽器中的DOM樹執(zhí)行,這樣就避免了冗余瑣碎的DOM樹操作負(fù)擔(dān),進(jìn)而有效提高了性能。基于 Virtual DOM 的數(shù)據(jù)更新與UI同步機(jī)制:初始渲染時(shí),首先將數(shù)據(jù)渲染為 Virtual DOM,然后由 Virtual DOM 生成 DOM。
圖6:vitual dom生成dom示意圖
比較兩個(gè) DOM 樹的差異是 Virtual DOM 算法最核心的部分,這也是所謂的 Virtual DOM 的diff 算法。diff算法的核心是比較只會在同層級進(jìn)行, 不會跨層級比較。而不像逐層逐層搜索遍歷的方式,時(shí)間復(fù)雜度將會達(dá)到 O(n^3)的級別,代價(jià)非常高,而只比較同層級的方式時(shí)間復(fù)雜度可以降低到O(n)。可以用一張圖示意:
圖7:virtual dom更新示意圖
數(shù)據(jù)更新時(shí),渲染得到新的 Virtual DOM,與上一次的 Virtual DOM 進(jìn)行 diff,得到所有需要在 DOM 上進(jìn)行的變更,然后在 patch 過程中應(yīng)用到 DOM 上實(shí)現(xiàn)UI的同步更新。因此 Virtual DOM算法主要包括這幾步: 初始化視圖的時(shí)候,用原生JS對象表示DOM樹,生成一個(gè)對象樹,然后根據(jù)這個(gè)對象樹來生成一個(gè)真正的DOM樹,插入到文檔中。 當(dāng)狀態(tài)更新的時(shí)候,重新生成一個(gè)對象樹,將新舊兩個(gè)對象樹做對比,記錄差異。 把記錄的差異應(yīng)用到第一步生成的真正的DOM樹上,視圖更新完成。 在vue中也是采用了virtual dom的diff算法如下圖,具體diff算法過程在patch函數(shù)執(zhí)行。
圖8:vitrual dom在vue中應(yīng)用
三、數(shù)據(jù)渲染過程 3.1 數(shù)據(jù)綁定實(shí)現(xiàn)邏輯 ---- initState 本節(jié)正式分析從new vue()到數(shù)據(jù)渲染到頁面的過程,在src/core/instance/index.js 中定義了一個(gè)Vue的構(gòu)造函數(shù)。當(dāng)執(zhí)行new Vue(options)時(shí)就會執(zhí)行this._init(options)這個(gè)函數(shù)。
圖9: vue構(gòu)造函數(shù)
以一個(gè)簡單的實(shí)例開始。定義如下模版和js代碼:
圖10: 實(shí)例
在調(diào)用Vue構(gòu)造函數(shù)時(shí)候傳入el和data。此時(shí)傳入this._init(options)中的options = { el: "#app", data: { message: "我是一條信息"}}。在_init函數(shù)中會執(zhí)行一系列初始化操作:初始化生命周期、初始化事件、初始化數(shù)據(jù)等。其中初始化數(shù)據(jù)是本節(jié)關(guān)心的內(nèi)容,跟數(shù)據(jù)綁定關(guān)聯(lián)最大的是 initState。因此我們現(xiàn)在重點(diǎn)研究一下initState(vm)。入口是src/core/instance/state.js。
圖11: initState函數(shù)
傳入data后會調(diào)用initData(vm)函數(shù),對data進(jìn)行處理。initData函數(shù)將當(dāng)前傳入的data賦值給vm._data。vm是當(dāng)前vue實(shí)例。然后會執(zhí)行代理函數(shù)proxy。
圖12: proxy函數(shù)
proxy函數(shù)的原理是通過 Object.defineProperty()函數(shù)在實(shí)例對象vm上定義與data數(shù)據(jù)字段同名的訪問器屬性,并且這些屬性代理的值是vm._data上對應(yīng)屬性的值。當(dāng)我們訪問vm[key] 就會通過get方法去訪問vm[sourceKey][key] 即vm._data[key]。也就是說vm.message 就會去訪問vm._data.message也就是vm.data.message。所以 this.message就是this._data.message,只不過_data是vue內(nèi)部使用的。這也就是我們通過this.message就能訪問到data里面的message對應(yīng)的值。即"我是一條信息‘。
圖13: 數(shù)據(jù)綁定過程
同理,當(dāng)我們設(shè)置一個(gè)屬性值時(shí)會通過set方法去設(shè)置vm._data[key]的值。到這一步我們已經(jīng)可以獲取傳入的data里面的數(shù)據(jù)了。那么message是如何渲染到頁面視圖層的呢?下一節(jié)就深入研究vue的掛載過程。 3.2 渲染函數(shù) ---- render 3.2.1 對el的處理 _init函數(shù)執(zhí)行完上述的初始化過程后會判斷是否傳入el,若傳入就執(zhí)行掛載函數(shù)$mount。
圖14: $mount函數(shù)
$mount首先會通過query(el)函數(shù)對傳入的el如下處理:
圖15: query函數(shù)
如果el是字符串則通過document.querySelector(el)方法查找該字符串對應(yīng)的dom元素。若沒找到,則通過方document.createElement("div")方法動(dòng)態(tài)創(chuàng)建一個(gè)div,若傳入的el是dom元素。那么就返回該元素。最終都是用一個(gè)dom元素來掛載實(shí)例。值得注意的是Vue 不能掛載在 body、html 這樣的根節(jié)點(diǎn)上。原因是vue在掛載是會將對應(yīng)的dom對象替換成新的div,但body和html是不適合替換的。如果el是body或者h(yuǎn)tml就會拋出警告,這也就是為什么平時(shí)我們通常會用“#app“或者“div“掛載實(shí)例的原因。 3.2.2 模版內(nèi)容提取 判斷是否傳入render函數(shù),如果渲染函數(shù)存在會直接調(diào)用運(yùn)行時(shí)版 $mount 函數(shù),我們知道運(yùn)行時(shí)版 $mount 僅有兩句代碼,且真正的掛載是通過調(diào)用 mountComponent 函數(shù)完成的,所以可想而知 mountComponent 完成掛載所需的必要條件就是:提供渲染函數(shù)給 mountComponent。 render分為用戶手寫和模版編譯兩種形式,手寫render函數(shù)格式如下。render函數(shù)的好處是,不會有在html中直接使用插值時(shí),在實(shí)際掛載前出現(xiàn){{message}}這樣的內(nèi)容。只有在render函數(shù)執(zhí)行完成后才會把message替換到頁面上去。這樣會有更好的體驗(yàn)。下面的render函數(shù)最終會渲染成一個(gè)id為app1,內(nèi)容為‘我是一條信息"的div元素,替換掉之前的掛載節(jié)點(diǎn)el。所以這也是為什么不使用body或者h(yuǎn)tml進(jìn)行掛載的原因,因?yàn)槲覀儾荒芨采w到整個(gè)body或者h(yuǎn)tml。
圖16: 手寫render函數(shù)
在 Vue 2.0 版本中,所有 Vue 的組件的渲染最終都需要 render 方法,無論我們是用單文件 .vue 方式開發(fā)組件,還是寫了 el 或者 template 屬性,最終都會轉(zhuǎn)換成 render 方法。我們的例子中沒有傳入render函數(shù),因此需要來研究一下在沒有傳入render函數(shù)的情況下如何通過模版編譯成render函數(shù)。
圖17: template處理
(1)如果存在template并且傳入的template是字符串,且以#開頭,如下:
圖18: template第一種形式
那么就找到id為#app的元素innerHtml();獲取該innerHtml()是在idToTemplate函數(shù)中進(jìn)行的。也是調(diào)用query函數(shù)獲取對應(yīng)的dom元素的innerHTML。并保存在template變量中。
圖19: idToTemplate函數(shù)
(2)如果傳入的template是dom節(jié)點(diǎn)。如下:那么直接將該節(jié)點(diǎn)的innerHtml賦值給template 變量。
圖20: template第二種形式
(3)如果options中沒有template,但是有el,那么就獲取el對應(yīng)元素的所有內(nèi)容。
圖21: el元素內(nèi)容提取
getOuterHTML 函數(shù)的源碼如下:
圖22: getOuterHTML函數(shù)
它接收一個(gè) DOM 元素作為參數(shù),并返回該元素的 outerHTML。該函數(shù)首先判斷了 el.outerHTML 是否存在,也就是說一個(gè)元素的 outerHTML 屬性未必存在,實(shí)際上在 IE9-11 中 SVG 標(biāo)簽元素是沒有 innerHTML 和 outerHTML 這兩個(gè)屬性的,解決這個(gè)問題的方案很簡單,可以把 SVG 元素放到一個(gè)新創(chuàng)建的 div 元素中,這樣新 div 元素的 innerHTML 屬性的值就等價(jià)于 SVG標(biāo)簽 outerHTML 的值。我們最初提供的實(shí)例子符合第(3)類情況。經(jīng)過以上邏輯的處理之后,理想狀態(tài)下此時(shí) template 變量應(yīng)該如下所示的一個(gè)模板字符串,將用于渲染函數(shù)的生成。
圖22: 提取的模版字符串
模版提取過程如圖23所示:
圖23: 模版提取
3.2.3 模版編譯成render函數(shù) 拿到模版內(nèi)容后就會調(diào)用compileToFunctions函數(shù)將模版編譯成render函數(shù)。下面看下compileToFunctions生成render方法的具體實(shí)現(xiàn)。編譯主要有三個(gè)過程:
圖23: 編譯過程
1.解析模版字符串生成AST ---- parse(template.trim(), options)。 parse 會用正則等方式解析 template模板中的指令、class、style等數(shù)據(jù),形成AST樹。AST是一種用Javascript對象的形式來描述整個(gè)模版。parse會調(diào)用parseHTML函數(shù),由于 parseHTML 的邏輯也非常復(fù)雜,因此我也用了偽代碼的方式表達(dá)。
圖24: parseHTML偽代碼
整體來說它的邏輯就是循環(huán)解析 template ,用正則做各種匹配,對于不同情況分別進(jìn)行不同的處理,直到整個(gè) template 被解析完畢。 在匹配的過程中會利用 advance 函數(shù)不斷前進(jìn)整個(gè)模板字符串,直到字符串末尾。
圖25: advance函數(shù)
為了更加直觀地說明 advance 的作用,可以通過一副圖表示:調(diào)用 advance 函數(shù):advance(4) 得到結(jié)果:
圖26: advance函數(shù)執(zhí)行示意圖
所以在整個(gè)html循環(huán)中會不斷調(diào)用advance函數(shù),達(dá)到把這個(gè)html解析完畢的目的。詳細(xì)過程有興趣的小伙伴自行去了解。那么至此,parse 的過程就分析完了,看似復(fù)雜,但我們可以拋開細(xì)節(jié)理清它的整體流程。
圖27: parse流程圖
parse 的目標(biāo)是把 template 模板字符串轉(zhuǎn)換成 AST 樹,它是一種用 JavaScript 對象的形式來描述整個(gè)模板。那么整個(gè) parse 的過程是利用正則表達(dá)式順序解析模板,當(dāng)解析到開始標(biāo)簽、閉合標(biāo)簽、文本的時(shí)候都會分別執(zhí)行對應(yīng)的回調(diào)函數(shù),來達(dá)到構(gòu)造 AST 樹的目的。個(gè)人理解就是把template(模板)解析成一個(gè)對象,該對象是包含這個(gè)模板所以信息的一種數(shù)據(jù),而這種數(shù)據(jù)瀏覽器是不支持的,為Vue后面的處理template提供基礎(chǔ)數(shù)據(jù)。本實(shí)例中會生成如下AST樹。
圖28: ast樹形結(jié)構(gòu)
2.優(yōu)化AST語法樹 ---- optimize(ast, options)。 為什么此處會有優(yōu)化過程?我們知道Vue是數(shù)據(jù)驅(qū)動(dòng),是響應(yīng)式的,但是template模版中并不是所有的數(shù)據(jù)都是響應(yīng)式的,也有許多數(shù)據(jù)是初始化渲染之后就不會有變化的,那么這部分?jǐn)?shù)據(jù)對應(yīng)的DOM也不會發(fā)生變化。后面有一個(gè) update 更新界面的過程,在這當(dāng)中會有一個(gè) patch 的過程, diff 算法會直接跳過靜態(tài)節(jié)點(diǎn),從而減少了比較的過程,優(yōu)化了 patch 的性能。
圖29: optimize流程
3.codegen:將優(yōu)化后的AST樹轉(zhuǎn)換成可執(zhí)行的代碼。
圖30: codegen流程
template模版經(jīng)歷過parse->optimize->codegen三個(gè)過程之后,就可以得到render function函數(shù)了。
圖31: 編譯后生成的render函數(shù)
從模版提取到render函數(shù)的生成的過程總結(jié)如下:
圖32: 編譯render函數(shù)的過程
3.3 render到VNode的生成 調(diào)用 render.call(vm._renderProxy, vm.$createElement)函數(shù)并返回生成的虛擬節(jié)點(diǎn)(vnode)。可以看到,render 函數(shù)中 createElement 方法就是 vm.$createElement 方法。
圖33: initRender函數(shù)
vm.$createElement 方法定義是在執(zhí)行 initRender 方法的時(shí)候,可以看到除了 vm.$createElement 方法,還有一個(gè) vm._c 方法,它是被模板編譯成的 render 函數(shù)使用,而 vm.$createElement 是用戶手寫 render 方法使用的,這倆個(gè)方法支持的參數(shù)相同,并且內(nèi)部都調(diào)用了 createElement 方法。
圖34: createElement函數(shù)
createElement 方法實(shí)際上是對 _createElement 方法的封裝,它允許傳入的參數(shù)更加靈活,在處理這些參數(shù)后,調(diào)用真正創(chuàng)建 VNode 的函數(shù) _crateElement 。_createElement最終實(shí)例化VNode,返回vnode或者一個(gè)空的vnode。
圖35: vnode實(shí)例化
本文例子生成如下的虛擬dom:
圖36:生成的vnode
簡單的梳理了createElement函數(shù)流程圖,可以參考下圖:
圖37:createElement函數(shù)流程圖
3.3虛擬DOM映射為真實(shí)DOM ----patch vm._render 函數(shù)的作用是生成的虛擬節(jié)點(diǎn)(vnode)。vm._update 函數(shù)的作用是把 vm._render 函數(shù)生成的虛擬節(jié)點(diǎn)渲染成真正的 DOM。
圖38:_update函數(shù)
update方法會在兩種情況下被調(diào)用,一是new Vue初始化的時(shí)候,還有一種情況就是當(dāng)我們改變data數(shù)據(jù),頁面重新渲染時(shí)調(diào)用。update最終會調(diào)用patch方法。patch實(shí)際調(diào)用的是createPatchFunction({ nodeOps, modules })。這個(gè)方法接收兩個(gè)參數(shù),nodeOps,modules。摘取一部分nodeOps內(nèi)容
圖39:nodeOps
可以看到,里面都是一些原生dom操作的封裝,摘取modules一部分內(nèi)容。
圖40:modules
可以看到,是一些對原生dom特性控制的封裝,以及一些輔助函數(shù), 下面我們回到createPatchFunction,createPatchFunction 方法中首先定義了好多的輔助函數(shù),最后返回了一個(gè)函數(shù),即patch,來看下這個(gè)patch。在該函數(shù)中,第一個(gè)參數(shù)是dom元素,第二個(gè)參數(shù)是vnode。
圖41:patch函數(shù)
一系列判斷過后會執(zhí)行emptyNodeAt()輔助函數(shù),可以看到,emptyNodeAt()函數(shù)的功能是創(chuàng)建一個(gè)新的vnode。因此oldVnode = emptyNodeAt(oldNode)創(chuàng)新了新的vnode替換,而原來的oldNode(dom節(jié)點(diǎn))可以在該vnode節(jié)點(diǎn)的elm元素中訪問到。
圖42:patch函數(shù)
取到當(dāng)前的el對應(yīng)的dom節(jié)點(diǎn)和其父節(jié)點(diǎn)后,開始利用createElm函數(shù)創(chuàng)建新的dom節(jié)點(diǎn)。在最初的實(shí)例中,oldElm就是id為app的div。而parentElm就是其父元素,即body。接下來調(diào)用createElm方法,這個(gè)方法定義于傳入的modules輔助函數(shù)中, 這個(gè)方法才是真實(shí)dom操作的核心所在,它的作用就是將vnode掛載到真實(shí)的dom上。我們進(jìn)入createElm。
圖43:createElm函數(shù)
在createElm()函數(shù)中,主要完成的功能是將構(gòu)建dom子節(jié)點(diǎn)插入到父節(jié)點(diǎn)中,并且一直循環(huán)到該節(jié)點(diǎn)沒有子節(jié)點(diǎn)為止。這個(gè)過程createElm()函數(shù)和createChildren函數(shù)一起完成。創(chuàng)建子節(jié)點(diǎn)
圖44:創(chuàng)建子節(jié)點(diǎn)
可以看到,在createChildren()函數(shù)中,如果該vnode的子節(jié)點(diǎn)是矩陣的話,就會調(diào)用createElm()函數(shù)。因此兩個(gè)函數(shù)是相互調(diào)用生成dom節(jié)點(diǎn),然后插入到父節(jié)點(diǎn)的過程。如果該子節(jié)點(diǎn)是最后一個(gè)節(jié)點(diǎn),則直接在dom節(jié)點(diǎn)后面插入該文本節(jié)點(diǎn)。最后調(diào)用insert將整個(gè)dom樹一次性插入到body中。上面從主線上完成模版和數(shù)據(jù)的渲染。
圖45:插入節(jié)點(diǎn)
此外,因?yàn)樾陆艘粋€(gè)div來渲染視圖,因此應(yīng)該把原來的就定義的用來掛載的dom節(jié)點(diǎn)(一般是個(gè)div)刪掉。所以,可以看到,在vue的渲染過程中,會創(chuàng)建新的dom節(jié)點(diǎn)替換掉以前的節(jié)點(diǎn),因此我們在初始化的時(shí)候不能將節(jié)點(diǎn)選擇掛載在html和body上。
圖46:刪除原節(jié)點(diǎn)
四、總結(jié) 回過頭來看,數(shù)據(jù)的渲染邏輯并不是特別復(fù)雜,核心關(guān)鍵的幾步流程還是非常清晰的:new Vue,執(zhí)行初始化,將傳入的data數(shù)據(jù)綁定到當(dāng)前實(shí)例,就可以通過this.message的形式訪問傳入的數(shù)據(jù)。這個(gè)過程是執(zhí)行initData()函數(shù)完成的。
掛載$mount方法,通過自定義Render方法、template、el等生成Render函數(shù)。如果傳入了模版(template)就將模版里面的內(nèi)容編譯成render函數(shù),否則將傳入的el對應(yīng)的元素的內(nèi)容編譯成render函數(shù)。編譯是調(diào)用compileToFunctions函數(shù)完成的。也可以自己手寫render函數(shù),可以減少編譯這一環(huán)節(jié)。其中render渲染函數(shù)的優(yōu)先級最高,template次之且需編譯成渲染函數(shù),而掛載點(diǎn)el屬性對應(yīng)的元素若存在,則在前兩者均不存在時(shí),其outerHTML才會用于編譯與渲染。
生成render函數(shù)后,調(diào)用_createElement函數(shù)生成vnode。
將虛擬DOM映射為真實(shí)DOM頁面上。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/6775.html
摘要:哪吒別人的看法都是狗屁,你是誰只有你自己說了才算,這是爹教我的道理。哪吒去他個(gè)鳥命我命由我,不由天是魔是仙,我自己決定哪吒白白搭上一條人命,你傻不傻敖丙不傻誰和你做朋友太乙真人人是否能夠改變命運(yùn),我不曉得。我只曉得,不認(rèn)命是哪吒的命。 showImg(https://segmentfault.com/img/bVbwiGL?w=900&h=378); 出處 查看github最新的Vue...
摘要:而組件在創(chuàng)建時(shí),又怎么會去調(diào)用呢這是由于將自身作為一個(gè)插件安裝到了,通過注冊了一個(gè)鉤子函數(shù),從而在之后所有的組件創(chuàng)建時(shí)都會調(diào)用該鉤子函數(shù),給了檢查是否有參數(shù),從而進(jìn)行初始化的機(jī)會。 vue-router 是 Vue.js 官方的路由庫,本著學(xué)習(xí)的目的,我對 vue-router 的源碼進(jìn)行了閱讀和分析,分享出來給其他感興趣的同學(xué)做個(gè)參考吧。 參考 源碼:vuejs/vue-route...
摘要:五六月份推薦集合查看最新的請點(diǎn)擊集前端最近很火的框架資源定時(shí)更新,歡迎一下。蘇幕遮燎沈香宋周邦彥燎沈香,消溽暑。鳥雀呼晴,侵曉窺檐語。葉上初陽乾宿雨,水面清圓,一一風(fēng)荷舉。家住吳門,久作長安旅。五月漁郎相憶否。小楫輕舟,夢入芙蓉浦。 五、六月份推薦集合 查看github最新的Vue weekly;請::點(diǎn)擊::集web前端最近很火的vue2框架資源;定時(shí)更新,歡迎 Star 一下。 蘇...
摘要:五六月份推薦集合查看最新的請點(diǎn)擊集前端最近很火的框架資源定時(shí)更新,歡迎一下。蘇幕遮燎沈香宋周邦彥燎沈香,消溽暑。鳥雀呼晴,侵曉窺檐語。葉上初陽乾宿雨,水面清圓,一一風(fēng)荷舉。家住吳門,久作長安旅。五月漁郎相憶否。小楫輕舟,夢入芙蓉浦。 五、六月份推薦集合 查看github最新的Vue weekly;請::點(diǎn)擊::集web前端最近很火的vue2框架資源;定時(shí)更新,歡迎 Star 一下。 蘇...
閱讀 3742·2021-11-22 13:52
閱讀 3622·2019-12-27 12:20
閱讀 2395·2019-08-30 15:55
閱讀 2150·2019-08-30 15:44
閱讀 2267·2019-08-30 13:16
閱讀 582·2019-08-28 18:19
閱讀 1891·2019-08-26 11:58
閱讀 3445·2019-08-26 11:47