深入但不淺出,你不知道的 Vue v-model 黑魔法。

Milk Midi
3 min readDec 24, 2019

--

大家好,我是奶綠茶
今天來研究 vue v-model 各種黑魔法。

首先要先了解一下,Vue template 語法
長的很像 html Code , 但他其實不是 html
所有寫的 vue template code 都會經過 vue compile 後,才重新 render 到網頁上。
所以 vue 做了什麼轉譯,不看原始碼和編譯後的結果,還真的不知道。

右邊是原始的 vue template 語法
左邊是經過 vue-loader compile 後的結果。
也就是 template code 最終都會轉成 vue 的 render function 寫法。

v-model 其實就是幫你加上 value 和 偵聽 input 事件
右圖的 二種 input 寫法,
比對左邊的圖就可以發現結果是相同的。
現在你終於知道 v-model 和 $event 是從哪來的了吧。

再來針對 input [type=”checkbox”] + v-model 來研究
checkbox 是多選,為什麼 Vue 知道那個被選取了?
他比對的條件是什麼 ?

右圖是大家常用的 checkbox v-model 寫法。
我們來看一下經過 compile 後的左圖。

遇到 checkbox ,v-model 改偵聽 change 事件
並判斷 v-model 是否為 Array
左圖有看到一行 _vm._i
_vm 指的就是物件自己,那 _i 是什麼?

在這可以看到 Vue 加工了其他的函式進來https://github.com/vuejs/vue/blob/dev/src/core/instance/render-helpers/index.js

再往下追
可以知道 _i 就是 looseIndexOf 函式
再追下去,就可以看到有個 looseEqual 函式
好了,答案出來了
每次的 checkbox change
vue 都會從 v-model Array ,用 looseEqual 來比對物件。
再找該 index 值後,slice Array。
https://github.com/vuejs/vue/blob/dev/src/shared/util.js#L325-L330

在這也可以看到 compile 時轉換的原始碼
https://github.com/vuejs/vue/blob/dev/src/platforms/web/compiler/directives/model.js#L67-L96

再來看一下 eventHandler

右圖可以看到 v-on:click 時,可以寫一個函式還有 $event
轉譯後的左圖就可以看到原來 $event 是怎麼產生的。

最後附上 github ,祝大家學習愉快。

--

--

No responses yet