上一節最後再次呼叫了mount函式,我發現竟然跳到了7000多行的那個函式,之前我還說因為宣告早了被覆蓋,看來我錯了!
就是這個函式:
// line-7531
vue$3.prototype.$mount = function(el, hydrating) ;
第一步query就不用看了,el此時是乙個dom節點,所以直接返回,然後呼叫了mountcomponent函式。
// line-2375
function mountcomponent(vm, el, hydrating) else ;
}// 生成中介軟體watcher
vm._watcher = new watcher(vm, updatecomponent, noop);
hydrating = false;
// 呼叫最後乙個鉤子函式
if (vm.$vnode == null)
return vm
}這個函式做了三件事,呼叫beforemount鉤子函式,生成watcher物件,接著呼叫mounted鉤子函式。
資料雙綁、ast物件處理完後,這裡的watcher物件負責將兩者聯絡到一起,上一張網上的:
可以看到,之前以前把所有的元件都過了一遍,目前就剩乙個watcher了。
構造新的eeyzvpwatcher物件傳了3個引數,當前vue例項、updatecomponent函式、空函式。
// line-2697
var watcher = function watcher(vm, exporfn, cb, options) else
this.cb = cb;
this.id = ++uid$2;
this.active = true;
this.dirty = this.lazy; // for lazy watchers
this.deps = ;
this.newdeps = ;
// 內容不可重複的陣列物件
this.depids = new _set();
this.newdepids = new _set();
// 把函式變成字串形式`
this.expression = exporfn.tostring();
// parse expression for getter
if (typeof exporfn === 'function') else ;
"development" !== 'production' && warn(
"failed watching path: \"" + exporfn + "\" " +
'watcher only accepts ****** dot-delimited paths. ' +
'for full control, use a function instead.',
vm);}}
// 不是懶載入型別呼叫get
this.value = this.lazy ?
undefined :
this.get();
};該建構函式新增了一堆屬性,第二個引數由於是函式,直接作為getter屬性加到watcher上,將字串後則作為expression屬性。
最後有乙個value屬性,由於lazy為false,呼叫原型函式gei進行賦值:
// line-2746
watcher.prototype.get = function get() catch (e)
} else
// "touch" every property so they are all tracked as
// dependencies for deep watching
if (this.deep)
poptarget();
this.cleanupdeps();
return value
};// line-750
dep.target = null;
var targetstack = ;
function pushtarget(_target)
// 依賴目前標記為當前watcher
dep.target = _target;
} function poptarget()
原型方法get中,先設定了依賴收集陣列dep的target值,user屬性暫時不清楚意思,跳到了else分支,呼叫了getter函式。而getter就是之前的updatecomponent函式:
// line-2422
updatecomponent = function() ;
這個函式不接受引數,所以說傳進來的兩個vm並沒有什麼卵用,呼叫這個函式會接著呼叫_update函式,這個是掛載到vue原型的方法:
// line-2422
vue.prototype._render = function()
}// 都沒有
vm.$scopedslots = (_parentvnode && _parentvnode.data.scopedslots) || emptyobject;
if (staticrenderfns && !vm._statictrees)
vm.$vnode = _parentvnode;
// render self
var vnode;
try catch (e)
// return empty vnode in case the render function errored out
if (!(vnode instanceof vnode))
// set parent
vnode.parent = _parentvnode;
return vnode
};方法獲取了一些vue例項的引數,比較重點的是render函式,呼叫了之前字串後的ast物件:
在這裡有點不一樣的地方,接下來的跳轉有點蒙,下節再說。
本文標題: vue之watcher原始碼解析(1)
本文位址:
Vue原始碼之createElement函式(五)
在render 函式中,最後呼叫的是createelement函式來返回vnode,那麼createelement函式到底完成了什麼功能 1.首先看一下vnode的定義 src core vdom vnode.js vnode被定義為乙個類。2.在createelement中,首先檢測data的型別...
vue原始碼之Array
目錄 響應式具體實現 陣列子集和新增元素的追蹤 array中的問題 object通過setter改變屬性的值,所以我們利用getter時傳送依賴收集,在setter時觸發依賴更新,而且vue將資料轉換成響應式資料是在資料初始化時,對object中之後的屬性新增和刪除操作,無法做到自動更新,而是通過v...
JDk原始碼解析之四 Vector原始碼解析
具體的三個屬性 解釋看圖中注釋。vector沒有採取arraylist臨界值擴容的辦法,而是每次不夠的時候,直接根據capacity的值來增加。具體怎麼增加後面會說。vector的構造方法如下。簡單粗暴,如果呼叫無參建構函式,直接就將初始容量設定成了10,最終在右側的構造方法裡,將陣列的長度設定為1...