Vue原始碼分析 v model實現原理

2021-09-07 20:54:32 字數 2085 閱讀 6744

最近小組有個關於vue原始碼分析的分享會,提前準備一下…

前言:我們都知道使用v-model可以實現資料的雙向繫結,及實現資料的變化驅動dom的更新,dom的更新影響資料的變化。那麼v-model是怎麼實現這一原理的呢?接下來探索一下這部分的原始碼。

gendirectives

在模板的編譯階段, v-model跟其他指令一樣,會被解析到 el.directives 中,之後會通過gendirectives方法處理這些指令,gendirectives方法位於src/compiler/codegen/index.js中:

我們去到之前建立的demo,找到demo中node_modules/vue/dist/vue.esm.js下的gendirectives方法,打上debugger,如圖:

可以看到傳進來的el是ast語法樹,el.directives是el上的指令,如下:

回到gendirectives原始碼,迴圈指令時都執行了const gen: directivefunction = state.directives[dir.name]這個方法,state.directives是什麼?

當遍歷到v-model的時候,dir.www.ysyl157.com   name為model,對應的state.directives[dir.name]相當於state.www.gouyiflb.cn  directives[model],directives的定義位於src/platforms www.dasheng178.com /web/compiler/directives/index.js 中:

本次分析的v-model,對應的也就是model方法,也就是其實!!gen(el, dir, state.warn)執行的是model方法,!!用於將返回值轉為boolean型別,model的定義位於index同目錄下。

model

model方法根據傳入的引數對tag的型別進行判斷,呼叫不同的處理邏輯,本demo中tag的型別為input,所以會執行gendefaultmodel方法,為了節約時間,就不去原始碼中找了,藏得比較深,直接在demo引用的單檔案原始碼vue.esm.js中搜尋gendefaultmodel。

gendefaultmodel

發現定義如下,打上debugger,以便除錯:

通過控制台檢視變數資訊,可以看到:

可以看到裡邊的genassignmentcode(value, valueexpression)在此demo中相當於genassignmentcode("msg", ""$event.target.value""),執行此方法後返回的是乙個字串:msg=$event.target.value,後來命中了needcompositionguard,所以code變成了if($event.target.composing)return;msg=$event.target.value,if($event.target.composing)return;的作用是不記錄使用者未確定的輸入,比如:

注釋掉if(needcompositionguard)的話使用者沒確定的也會展示,如圖:

隨後會依次執行以下兩個方法:

addprop

先注釋掉addhandler,避免對研究此方法產生影響。

可以看到此方法的功能為給el新增props,首先判斷el上有沒有props,如果沒有的話建立props並賦值為乙個空陣列,隨後拼接物件並推到props中,**在此demo中相當於push了,列印一下這番操作後的el,可以看到新增了props的el的結構如下:

這個方法其實是在input上動態繫結了value,此時,原本的相當於變成了,隨後繼續執行addhandler。

addhandler

以下僅包含關鍵**,打上debugger以便檢視資料。

控制台檢視el的debuuger結果:

可以看到比執行addhandler之前,el上多了events,可以得知這個方法主要給el 新增了事件處理,在此demo中的話相當於在 input 上繫結了 input 事件。

總結:也就是說,到此為止,原本的相當於變成了,當使用者輸入的使用觸發msg=$event.target.value進而更新msg,msg通過v-bind繫結到輸入框的value上。

即,以下兩份**其實是乙個意思。

第乙份:

第二份

Vue原始碼分析

在開始原始碼分析工作之前,我們在當前篇章做好相應的準備工作,以便更好地展開分析。將原始碼fork到自己的github倉庫中 git clone 自己的github vue 位址 dist 打包之後的結果 examples 示例 src compiler 編譯相關 core vue 核心庫 compo...

Vue原始碼分析(流程分析)

使用步驟 1.編寫 頁面 模板 1.直接在html標籤中寫 2.使用template 3.使用單檔案 2.建立vue例項 1.在vue 的建構函式中 data,methods,computer,watcher,props,3.將vue掛載到頁面中 mount 資料驅動模型 vue執行流程 1.獲得模...

LinkedHashMap原始碼分析及實現LRU演算法

ps 要先了解hashmap的實現原理hashmap原始碼分析 可以看到linkedhashmap繼承了hashmap,其實際是在hashmap基礎上,把資料節點連成乙個雙向鍊錶,遍歷的時候按鍊錶順序遍歷。小總結預設的linkedhashmap 的遍歷會按照插入的順序遍歷出來,hashmap則不保證...