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=trueMutationObserver是一个构造器,接受一个callback参数,用来处理节点变化的回调函数,observe方法中options参数characterData:设置true,表示观察目标数据的改变
_render函数
通过执行createElement方法并返回的是vnode,它是一个虚拟的Node。
vnode=render.call(vm._renderProxy,vm.$createElement)总结
以上所述是小编给大家介绍的vue源码解析之虚拟Dom-render,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。