//有乙個值得注意的點是,原始碼中有2個$mount函式都是vue$3的原型函式,其中乙個標記了注釋public mount method,在7531行,另外乙個在9553行。打斷點進入的是後面,因為定義的晚,覆蓋了前面的函式。line-3924
vue.prototype._init = function
(options)
};
(時隔多日,我終於看懂了,這裡首先定義了原型方法$mount,然後將其賦給了乙個變數mount,然後重新定義此方法,所以呼叫mount.call會呼叫第一次定義的$mount,vue原型上最終只有第二次定義的$mount) => 多此一舉! 2017.7.31
//現在進入後面的$mount函式看看內部結構:line-7531
//public mount method
vue$3.prototype.$mount = function
(el,hydrating) ;
//line-9552
var mount = vue$3.prototype.$mount;
vue$3.prototype.$mount = function
( el,
hydrating
) ;
//**前半段首先將el轉換為dom節點,並判斷是否掛載到body或者html標籤,看看簡單的query函式:line-9552
var mount = vue$3.prototype.$mount;
vue$3.prototype.$mount = function
(el,hydrating)
var options = this
.$options;
//處理template/el 轉換為渲染函式
if (!options.render)
return mount.call(this
, el, hydrating)
};
//函式比較簡單,值得注意的乙個點是,由於呼叫的是queryselector方法,所以可以傳標簽名、類名、c3新選擇器等,都會返回查詢到的第乙個。當然,總是傳乙個id或者確定的dom節點才是正確用法。line-4583
function
query(el)
return
selected
}//不是字串就預設傳進來的是dom節點
else
}
下面看接下來的**:
//由於沒有template屬性,會直接進入第二個判斷條件,呼叫getouterhtml來初始化template變數,函式比較簡單, 來看看:line-9552
var mount = vue$3.prototype.$mount;
vue$3.prototype.$mount = function
(el,hydrating) }}
else
if(template.nodetype)
else
return
this
} }
//有el 獲取字串化的dom樹
else
if(el)
if(template)
}return mount.call(this
, el, hydrating)
};
//簡單來講,就是呼叫outerhtml返回dom樹的字串形式,看圖就明白了:line-9623
function
getouterhtml(el)
//相容ie中的svg
else
}
下面看最後一段**:
//忽略2段dev模式下的提示**,剩下的**做了3件事,呼叫compiletofunctions函式肢解dom樹字串,將返回的物件屬性新增到options上,再次呼叫mount函式。line-9552
var mount = vue$3.prototype.$mount;
vue$3.prototype.$mount = function
(el,hydrating)
//將dom樹字串編譯為函式
var ref =compiletofunctions(template, ,
this
);
//options新增屬性
var render =ref.render;
var staticrenderfns =ref.staticrenderfns;
options.render =render;
options.staticrenderfns =staticrenderfns;
//編譯結束
if ("development" !== 'production' && config.performance &&mark) }}
return mount.call(this
, el, hydrating)
};
首先看一下compiletofunctions函式,該函式接受3個引數,分別為字串、配置物件、當前vue例項。
由於函式比較長,而且部分是錯誤判斷,簡化後如下:
//可以看到,這個函式流程可以分為4步,獲取引數 => 呼叫compile函式進行編譯 => 將得到的compiled轉換為函式 => 返回並快取。line-9326
function
compiletofunctions(template,options,vm) ;
//...
var key = options.delimiters ?string(options.delimiters) +template :
template;
//檢測快取
if(functioncompilecache[key])
//1var compiled =compile(template, options);
//...//2
var res ={};
var fngenerrors =;
res.render =makefunction(compiled.render, fngenerrors);
var l =compiled.staticrenderfns.length;
res.staticrenderfns = new
array(l);
for (var i = 0; i < l; i++)
//...//3
return (functioncompilecache[key] =res)
}
第一節現在這樣吧。一張圖總結下:
Vue之Watcher原始碼解析(1)
上一節最後再次呼叫了mount函式,我發現竟然跳到了7000多行的那個函式,之前我還說因為宣告早了被覆蓋,看來我錯了!就是這個函式 line 7531 vue 3.prototype.mount function el,hydrating 第一步query就不用看了,el此時是乙個dom節點,所以直...
vue原始碼分析1
在vue的原始碼中使用的是es5的方法 prototype.slice.bind obj 來實現的 例如 已 為例 obj 定義屬性的物件 prop 定義或修改屬性的名稱 descriptor 將被定義或修改的屬性描述符 value 預設值 configurable 是否可以重新定義 enumera...
Vue 原始碼閱讀1之開篇感悟
隨著網際網路的大風越刮越大,前端的發展也是十分的迅猛,出現了各種各樣的前端框架,vue是其中的佼佼者,這一系列的文章我將以初學者的身份分析vue的相關實現,希望能夠和大家一起進步,早日實現高薪。我個人感覺要要學習vue的原始碼,vue的生命週期是離不開的話題,每個人都知道vue的生命週期為befor...