vue2原始碼 深度理解Vue中v model原理

2021-10-09 22:17:29 字數 4799 閱讀 4358

value+input方法的語法糖

可繫結:input,checkbox,select,textarea,radio

v-model一種是在表單元素上使用,另外一種是在元件上使用

此預設繫結input,v-model繫結值為value,預設在注釋中逐行解釋

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

gendirectives

src/compiler/codegen/index.js

function

gendirectives

(el, state)

var res =

'directives:['

;var hasruntime =

false

;var i, l, dir, needruntime;

// dirs是個陣列,gendirectives方法中遍歷處理這些指令

for(i =

0, l = dirs.length; i < l; i++

)}

執行model()model

function

model

(el,dir,_warn)

else

if(tag ===

'select'

)else

if(tag ===

'input'

&& type ===

'checkbox'

)else

if(tag ===

'input'

&& type ===

'radio'

)else

if(tag ===

'input'

|| tag ===

'textarea'

)elseif(

!config.

isreservedtag

(tag)

)else

// ensure runtime directive metadata

return

true

}

進入到gendefaultmodel執行方法gendefaultmodel

// input --- 執行gendefaultmodel方法

function

gendefaultmodel

(el,value,modifiers)

}// 獲取修飾符lazy, number及trim

var ref = modifiers ||

;var lazy = ref.lazy;

var number = ref.number;

var trim = ref.trim;

var needcompositionguard =

!lazy && type !==

'range'

;// .lazy 取代input監聽change事件

var event = lazy

?'change'

: type ===

'range'

?range_token

:'input'

;var valueexpression =

'$event.target.value'

;// .trim 輸入首尾空格過濾

if(trim)

// .number 輸入字串轉為數字

if(number)

// 接下來

}

接下來

//獲取code

var code =

genassignmentcode

(value, valueexpression);if

(needcompositionguard)

// 繫結value

addprop

(el,

'value',(

"("+ value +

")"));

// 給el新增input事件處理

addhandler

(el, event, code,

null

,true);

if(trim || number)

if($ event.target.composing)return;不記錄使用者未確定的輸入

value=$event.target.value在genassignmentcode方法中返回

使用者未確定的輸入:

aaaaa就是已確定輸入,bbbbb就是未確定輸入

genassignmentcode

// 生成model中繫結的value值,返回code

function

genassignmentcode

( value,

assignment

)else

}

$set

// value屬性是否一開始就在obj中

// 如果存在就只是進行單純的賦值

// 不存在的話在進行響應式操作

function

set(target, key, val)

// definereactive為value繫結getter()和setter()

definereactive$$1

(ob.value, key, val)

; ob.dep.

notify()

;return val

}

addprop

function

addprop

(el, name, value, range, dynamic)

, range));

el.plain =

false

;}

addprop的作用是讓input動態繫結value

讓原本的變成

然後繼續執行addhandler

addhandler的作用是讓input動態繫結input

讓原本的變成

當有乙個自定義的元件時,子元件通過this.$emit(『input』,value)來對父元件傳值,父元件接受到之後讓e.target.value賦值給input中的value從而實現元件內部暴露出元件的值到 v-model所繫結的值中去

原生控制項繫結事件,捕捉到原生元件的值,利用 $emit方法,觸發input方法,元件監聽到 input事件然後把值傳入到value中

自定義model時,只需要在元件中傳入model的prop和event屬性

createcomponent

src/core/vdom/create-component.js

// 如果當前資料有model屬性,就會使用transformmodel轉換modelif(

isdef

(data.model)

)

transformmodelsrc/core/vdom/create-component.js

function

transformmodel

(options, data: any)))

[prop]

= data.model.value// data.attrs.value="***"

const on = data.on ||

(data.on =

)const existing = on[event]

// 給on繫結input的事件,對應的函式就是callback

const callback = data.model.callback

if(isdef

(existing))}

else

}

自定義model:

const vuetemplatecompiler =

require

('vue-template-compiler');

const ele = vuetemplatecompiler.

compile(''

);// 解析後

with

(this),

expression:

"check"}}

)}

傳入prop和event後對應的轉換

vue.

component

('el-checkbox',,

props:

})

《Vue2 十一》Vue中的混入

mixin用來分發vue元件中可復用的功能。乙個混入物件可以包含任意元件選項。當元件使用混入物件時,混入物件的所有選項將被混合進該元件本身的選項。定義區域性混入 定義乙個混入物件 var mymixin methods 定義乙個使用混入物件的元件 var component vue.extend 定...

vue2原始碼 響應式處理(學習筆記) 2

index.html檔案 一下是手寫vue的js邏輯 檔案層層下去乙個個建就好了 import from init function vue options 擴充套件原型 initmixin vue export default vue import from state export functi...

vue2新人入門

預設對webpack,sass,npm有一定的了解。一些vue指令不會說,反正官方文件有,我也懶得抄。一 超級基礎部分 1.全域性安裝 npm install globall vue cli 已全域性安裝了的不必安裝 2.建立乙個基於webpack的模板專案 vue init webpack 你的專...