寫文章不容易,點個讚唄兄弟 專一 Vue 源碼分享,文章分爲白話版和 源碼版,白話版助於理解工做原理,源碼版助於瞭解內部詳情,讓咱們一塊兒學習吧 研究基於 Vue版本 【2.5.17】node
若是你以爲排版難看,請點擊 下面連接 或者 拉到 下面關注公衆號也能夠吧bash
【Vue原理】Event - 源碼版 之 綁定組件DOM事件 函數
上一篇已經說了綁定正常標籤的原生事件,今天是組件的原生事件,二者最終做用是同樣的,可是過程有少少不一樣學習
最近更新快是由於文章早就寫完了,只是定時發而已哈哈ui
官網已經說明,要是想在組件上綁定原生事件,須要加上 native 修飾符spa
這裏同樣,解析不是本文重點,只給出結果prototype
如今,我有這麼一個模板3d
被解析成這樣的渲染函數 code
這個VNode 是 外殼vnode,咱們已經知道外殼 vnode 是保存 父子組件關聯的數據cdn
好比 props,事件之類的
因此你在組件上綁定的原生事件,天然而然就是保存在 外殼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]
);
}
}
}
複製代碼