vue 源码解析之虚拟Dom-render
vue源码解析--虚拟Dom-render
instance/index.js
functionVue(options){
if(process.env.NODE_ENV!=='production'&&
!(thisinstanceofVue)
){
warn('Vueisaconstructorandshouldbecalledwiththe`new`keyword')
}
this._init(options)
}
renderMixin(Vue)
初始化先执行了renderMixin方法,Vue实例化执行this._init,执行this.init方法中有initRender()
renderMixin
installRenderHelpers(将一些渲染的工具函数放在Vue原型上)
Vue.prototype.$nextTick=function(fn:Function){
returnnextTick(fn,this)
}
仔细看这个函数,在Vue中的官方文档上这样解释
Vue异步执行DOM更新。只要观察到数据变化,Vue将开启一个队列,并缓冲在同一事件循环中发生的所有数据改变。如果同一个watcher被多次触发,只会被推入到队列中一次。这种在缓冲时去除重复数据对于避免不必要的计算和DOM操作上非常重要。然后,在下一个的事件循环“tick”中,Vue刷新队列并执行实际(已去重的)工作。Vue在内部尝试对异步队列使用原生的Promise.then和MessageChannel,如果执行环境不支持,会采用setTimeout(fn,0)代替。
exportfunctionnextTick(cb?:Function,ctx?:Object){
let_resolve
callbacks.push(()=>{
if(cb){
try{
cb.call(ctx)
}catch(e){
handleError(e,ctx,'nextTick')
}
}elseif(_resolve){
_resolve(ctx)
}
})
if(!pending){
pending=true
timerFunc()
}
//$flow-disable-line
if(!cb&&typeofPromise!=='undefined'){
returnnewPromise(resolve=>{
_resolve=resolve
})
}
}
Vue.nextTick用于延迟执行一段代码,它接受2个参数(回调函数和执行回调函数的上下文环境),如果没有提供回调函数,那么将返回promise对象。
functionflushCallbacks(){
pending=false
constcopies=callbacks.slice(0)
callbacks.length=0
for(leti=0;i
这个flushCallbacks是执行callbacks里存储的所有回调函数。
timerFunc用来触发执行回调函数
先判断是否原生支持promise,如果支持,则利用promise来触发执行回调函数;
否则,如果支持MutationObserver,则实例化一个观察者对象,观察文本节点发生变化时,触发执行
所有回调函数。
如果都不支持,则利用setTimeout设置延时为0。
constobserver=newMutationObserver(flushCallbacks)
consttextNode=document.createTextNode(String(counter))
observer.observe(textNode,{
characterData:true
})
timerFunc=()=>{
counter=(counter+1)%2
textNode.data=String(counter)
}
isUsingMicroTask=true
MutationObserver是一个构造器,接受一个callback参数,用来处理节点变化的回调函数,observe方法中options参数characterData:设置true,表示观察目标数据的改变
_render函数
通过执行createElement方法并返回的是vnode,它是一个虚拟的Node。
vnode=render.call(vm._renderProxy,vm.$createElement)
总结
以上所述是小编给大家介绍的vue源码解析之虚拟Dom-render,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。