Vue之Watcher原始碼解析(1)

2022-10-04 05:48:08 字數 3016 閱讀 5492

上一節最後再次呼叫了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...