人源解析Vue公司(1)

在最后一节中,我再次调用挂载函数,我发现我跳到了超过7000行的函数。在我说之前,我错了,因为声明被重写了。

这是函数:


/ / line-7531
Vue 3美元。原型。$山=功能(EL保湿){
EL = EL inbrowser查询(EL):定义;
返回mountcomponent(今El、保湿)
};



第一步是看不到的查询,EL是在这个时候一个DOM节点,因此它直接返回,然后调用mountcomponent功能。


/ / line-2375
功能mountcomponent(VM,El、保湿){
虚拟机;
检测虚拟机。$ options.render / * * /

调用钩子函数
CallHook(VM,'beforemount);

无功updatecomponent;
伊斯坦布尔是否忽略
如果(development'production'config性能。!=标记){
马克Vue PERF / * * /
{人}
updatecomponent =函数(){
虚拟机(VM。_update。_render()、保湿);
};
}

生成中间件监视程序
VM。_watcher =新观察家(VM,updatecomponent,空);
水合=假;

在钩子函数调用结束时
如果(= =空节点的虚拟机。$){
_ismounted =真正的虚拟机;
CallHook(VM,'mounted);
}
返回虚拟机
}




这个函数做了三件事,称beforemount钩子函数,生成的监控对象,然后调用安装钩子函数。

当数据被绑定并处理AST对象时,这里的监视对象负责将两个对象连接到Internet上的图片:


正如你所看到的,所有的组件都已经被传递过,并且还有一个观察者离开了。

一个新的监控对象的建设是通过3个参数,当前实例的Vue,updatecomponent功能,空函数。


/ / line-2697
无功者=功能监视器(VM,exporfn、CB、期权){
this.vm = VM;
守望者 / /添加到Vue实例
VM _watchers.push(本);
false的默认配置参数/
如果(选项){
this.deep =!options.deep;
this.user =!options.user;
this.lazy =!options.lazy;
this.sync =!options.sync;
{人}
this.deep = this.user = this.lazy = this.sync = false;
}
this.cb = CB;
this.id = + + UID 2美元;
this.active =真;
this.dirty = this.lazy; / /懒惰的人
this.deps = { };
this.newdeps = { };
内容不是可重复的数组对象。
this.depids =新_set();
this.newdepids =新_set();
将函数放入字符串中。
this.expression = exporfn.tostring();
表达式解析
如果(typeof exporfn = 'function){
this.getter = exporfn;
{人}
this.getter = parsepath(exporfn);
如果(!这个吸气器{){
this.getter =函数(){ };
发展生产的(警告= =!
没看道:+ exporfn ++++
观察者只接受简单的点分隔路径。+
要完全控制,请使用函数代替,
VM
);
}
}
不延迟加载类型
this.value = this.lazy
未定义:
This.get();
};



构造函数添加了一系列属性。第二个参数是函数。它直接作为观察者属性添加到观察者,然后将字符串作为表达式属性。

最后,有一个价值属性,因为懒惰是假的,原型功能给调用分配一个值:




/ / line-2746
watcher.prototype.get =函数(){
PushTarget(本);
VaR值;
VaR VM = this.vm;
如果(这个用户){
{试
价值= this.getter.call(VM,VM);
} catch(e){
HandleError(E,VM,(王守望者+(的表达)+ ))))
}
{人}
打电话前 / / updatecomponent
价值= this.getter.call(VM,VM);
}
触摸每个属性,所以它们都被跟踪为
用于深入查看/依赖关系
如果(此深){
遍历(值);
}
PopTarget();
This.cleanupDeps();
返回值
};

/ / line-750
dep.target = null;
无功targetstack = { };

功能pushtarget(_target){
默认值为空/
如果(dep.target){
TargetStack.push(dep.target);
}
当前观察者/依赖的标记
dep.target = _target;
}

功能poptarget(){
dep.target = targetstack.pop();
}




在原型的方法得到的,依赖于阵列Dep收集目标值设置,用户属性暂时不清楚,跳转到其他的分支,和getter函数被调用,吸气是以前的updatecomponent功能:


/ / line-2422
updatecomponent =函数(){
虚拟机(VM。_update。_render()、保湿);
};



此函数不接受参数,因此导入的两个VM没有任何卵子。调用此函数将调用_update功能,即安装到Vue原型的方式。


/ / line-2422
Vue。原型。_render =函数(){
var =;
var选项;
var = ref.render渲染;
无功staticrenderfns = ref.staticrenderfns;
无功_parentvnode = ref._parentvnode;
检测是否安装了
如果(VM。_ismounted){
重新呈现/克隆的槽节点
用于(var中的var键)
虚拟机。$槽{key} = clonevnodes(VM。$槽{key});
}
}
/否
VM。scopedslots美元= emptyobject(_parentvnode _parentvnode。数据。scopedslots)| |;
如果(staticrenderfns!VM。_statictrees){
VM。_statictrees = { };
}
美元= _parentvnode节点的虚拟机;
渲染/自我
Var vnode;
{试
调用前呈现字符串函数
vnode = render.call(VM,VM _renderproxy,createElement美元。);
} catch(e){
处理程序错误
}
返回空节点的情况下, /渲染函数出错了
如果(!(vnode instanceof VNode)){
错误
createemptyvnode vnode =();
}
设置/父/父
vnode.parent = _parentvnode;
返回节点
};



方法获取一些Vue实例的参数,着重渲染功能,它调用对象上的字符串后AST:



这里有一个不同的地方,下一跳是一点点,下一节。


以上是本文的全部内容,希望能对您有所帮助,希望大家多多支持。