寫文章不容易,點個讚唄兄弟
專一 Vue 源碼分享,文章分爲白話版和 源碼版,白話版助於理解工做原理,源碼版助於瞭解內部詳情,讓咱們一塊兒學習吧
研究基於 Vue版本 【2.5.17】
若是你以爲排版難看,請點擊 下面連接 或者 拉到 下面關注公衆號也能夠吧node
【Vue原理】Event - 源碼版 之 綁定組件DOM事件 函數
上一篇已經說了綁定正常標籤的原生事件,今天是組件的原生事件,二者最終做用是同樣的,可是過程有少少不一樣學習
最近更新快是由於文章早就寫完了,只是定時發而已哈哈spa
官網已經說明,要是想在組件上綁定原生事件,須要加上 native 修飾符prototype
這裏同樣,解析不是本文重點,只給出結果3d
如今,我有這麼一個模板code
被解析成這樣的渲染函數
而後生成這樣的 VNodeblog
這個VNode 是 外殼vnode,咱們已經知道外殼 vnode 是保存 父子組件關聯的數據事件
好比 props,事件之類的rem
因此你在組件上綁定的原生事件,天然而然就是保存在 外殼vnode 上啦
綁定在 外殼vnode 的數據,是要在解析組件內部模板時,纔會拿出來使用的
而後!
你能夠看到,nativeOn 和 on 都保存有事件
其實解析的時候,只保存在了 nativeOn,on 是 後面 從 nativeOn 直接賦值過去的
打印組件實例能夠看到
耶!Vnode 相關又能夠看這篇哦
綁定的流程千篇一概,可是有少少出入
能夠參考我這篇,綁定原生事件的文章
【Vue原理】Event - 源碼版 之 綁定標籤DOM事件
相同的地方簡單提一下,不一樣的地方再仔細說
一、綁定事件發生在 掛載DOM的階段,從 Vue.prototype._update 開始
二、_update 其中會調用 createElm 來生成DOM
三、createElm 碰到組件,會轉去解析組件
function createElm(vnode) { if ( createComponent(vnode, parentElm, refElm) ) { return } ....普通標籤的DOM生成和掛載 }
進入到 createComponent
function createComponent(vnode, parentElm, refElm) { var i = vnode.data; if (isDef(i)) { // ... 建立組件實例 if (若是組件實例已經建立成功) { initComponent(vnode); return true } } }
沒啥好說的,繼續轉到了另外一個函數
function initComponent(vnode) { invokeCreateHooks(vnode); }
而後這個函數仍是爲了調用 invokeCreateHooks 這個函數
invokeCreateHooks 上篇文章也出現過,做用是調用各類數據處理函數,好比處理 prop,class 等,其中還包括處理事件的函數 updateDOMListeners
updateDOMListeners 這個函數在上一篇文章中已經說過啦,你們能夠看一下
Event - 源碼版 之 綁定標籤DOM事件
可是我依然給複製源碼到這裏,可是不寫解析
function updateDOMListeners(oldVnode, vnode) { var on = vnode.data.on || {}; var oldOn = oldVnode.data.on || {}; var target = vnode.elm; // 遍歷綁定的事件 for (name in on) { newHandler = on[name]; oldHandler = oldOn[name]; // 沒有舊事件,就直接添加新事件 if (typeof oldHandler === "undefined") { // 給事件回調包裝一層 target.addEventListener(name, function(){ on[name]() // 執行保存在vnode的事件 }); } // 新事件和舊事件不同,替換舊事件 else if (newHandler !== oldHandler) { on[name] = newHandler; } } // 移除舊事件 for (name in oldOn) { // 舊事件不存在新事件中,直接移除 if (typeof on[name] === "undefined") { target.removeEventListener( name, oldOn[name] ); } } }