日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 前端技术 > vue >内容正文

vue

[Vue源码分析] v-model实现原理

發(fā)布時(shí)間:2023/12/31 vue 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [Vue源码分析] v-model实现原理 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

最近小組有個(gè)關(guān)于vue源碼分析的分享會(huì),提前準(zhǔn)備一下…

前言:
我們都知道使用v-model可以實(shí)現(xiàn)數(shù)據(jù)的雙向綁定,及實(shí)現(xiàn)數(shù)據(jù)的變化驅(qū)動(dòng)dom的更新,dom的更新影響數(shù)據(jù)的變化。那么v-model是怎么實(shí)現(xiàn)這一原理的呢?接下來(lái)探索一下這部分的源碼。

前期準(zhǔn)備

①:vue2.5.2源碼(用于閱讀、查看關(guān)聯(lián)等)
②:建立vue demo,創(chuàng)建包含v-model指令的實(shí)例(用于debugger)
以下為demo:

genDirectives

在模板的編譯階段, v-model跟其他指令一樣,會(huì)被解析到 el.directives 中,之后會(huì)通過(guò)genDirectives方法處理這些指令,genDirectives方法位于src/compiler/codegen/index.js中:

我們?nèi)サ街敖⒌膁emo,找到demo中node_modules/vue/dist/vue.esm.js下的genDirectives方法,打上debugger,如圖:

可以看到傳進(jìn)來(lái)的el是ast語(yǔ)法樹(shù),el.directives是el上的指令,如下:


回到genDirectives源碼,循環(huán)指令時(shí)都執(zhí)行了const gen: DirectiveFunction = state.directives[dir.name]這個(gè)方法,state.directives是什么?
當(dāng)遍歷到v-model的時(shí)候,dir.name為model,對(duì)應(yīng)的state.directives[dir.name]相當(dāng)于state.directives[model],directives的定義位于src/platforms/web/compiler/directives/index.js 中:

本次分析的v-model,對(duì)應(yīng)的也就是model方法,也就是其實(shí)!!gen(el, dir, state.warn)執(zhí)行的是model方法,!!用于將返回值轉(zhuǎn)為Boolean類型,model的定義位于index同目錄下。

model


model方法根據(jù)傳入的參數(shù)對(duì)tag的類型進(jìn)行判斷,調(diào)用不同的處理邏輯,本demo中tag的類型為input,所以會(huì)執(zhí)行g(shù)enDefaultModel方法,為了節(jié)約時(shí)間,就不去源碼中找了,藏得比較深,直接在demo引用的單文件源碼vue.esm.js中搜索genDefaultModel。

genDefaultModel

發(fā)現(xiàn)定義如下,打上debugger,以便調(diào)試:

通過(guò)控制臺(tái)查看變量信息,可以看到:

可以看到里邊的genAssignmentCode(value, valueExpression)在此demo中相當(dāng)于genAssignmentCode("msg", ""$event.target.value""),執(zhí)行此方法后返回的是一個(gè)字符串:msg=$event.target.value,后來(lái)命中了needCompositionGuard,所以code變成了if($event.target.composing)return;msg=$event.target.value,if($event.target.composing)return;的作用是不記錄用戶未確定的輸入,比如:

注釋掉if(needCompositionGuard)的話用戶沒(méi)確定的也會(huì)展示,如圖:

隨后會(huì)依次執(zhí)行以下兩個(gè)方法:

addProp

先注釋掉addHandler,避免對(duì)研究此方法產(chǎn)生影響。

可以看到此方法的功能為給el添加props,首先判斷el上有沒(méi)有props,如果沒(méi)有的話創(chuàng)建props并賦值為一個(gè)空數(shù)組,隨后拼接對(duì)象并推到props中,代碼在此demo中相當(dāng)于push了{(lán)name: "value", value: "(msg)"},打印一下這番操作后的el,可以看到添加了props的el的結(jié)構(gòu)如下:

這個(gè)方法其實(shí)是在input上動(dòng)態(tài)綁定了value,此時(shí),原本的<input v-model="msg">相當(dāng)于變成了<input v-bind:value="msg">,隨后繼續(xù)執(zhí)行addHandler。

addHandler

以下僅包含關(guān)鍵代碼,打上debugger以便查看數(shù)據(jù)。

控制臺(tái)查看el的debuuger結(jié)果:

可以看到比執(zhí)行addHandler之前,el上多了events,可以得知這個(gè)方法主要給el 添加了事件處理,在此demo中的話相當(dāng)于在 input 上綁定了 input 事件。

總結(jié):

也就是說(shuō),到此為止,原本的<input v-model="msg">相當(dāng)于變成了<input v-bind:value="msg" v-on:input="msg=$event.target.value">,當(dāng)用戶輸入的使用觸發(fā)msg=$event.target.value進(jìn)而更新msg,msg通過(guò)v-bind綁定到輸入框的value上。
即,以下兩份代碼其實(shí)是一個(gè)意思。
第一份:

第二份

總結(jié)

以上是生活随笔為你收集整理的[Vue源码分析] v-model实现原理的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。