亲爱哒朋友们,今天咱来聊聊Vue那个超厉害的功能!为啥数据一换,view也跟着动了?真的好让人心生疑惑耶!
// 来自mountComponent函数 updateComponent = function () { vm._update(vm._render(), hydrating); }; new Watcher(vm, updateComponent, noop, { before: function before () { if (vm._isMounted) { callHook(vm, 'beforeUpdate'); } } }, true /* isRenderWatcher */);
你知道吗?在玩儿Vue时,”数据驱动”可是个要紧事儿!每个Vue实例里的data属性都有个”监视器”,数据一动,立马告诉大家。特别是render,它在data的包裹下,所以data一有变化,render也随之改变。
var patch = createPatchFunction({ nodeOps: nodeOps, modules: modules }); Vue.prototype.__patch__ = inBrowser ? patch : noop;
问题来啦:这个数据系统怎就保证每次更新都能使我们制作出来的画面牛得要飞起来?
答:其实秘密在 updateComponent这个小程序里!它的任务就是把组件修理好,然后让vm._update知道,再由vm._render传达给它。如果你仔细看 _update 的代码,你会发现它直接巧妙地叫出了vm.__patch__,还从createPatchFunction那里得到了反馈。
if (isUndef(vnode)) { if (isDef(oldVnode)) { invokeDestroyHook(oldVnode); } return }
if (isUndef(oldVnode)) { // empty mount (likely as component), create new root element isInitialPatch = true; createElm(vnode, insertedVnodeQueue); }
好,我们来聊聊这个create Patch Function是怎么发挥作用的!简单来说如果新的vnode根本没有出现过,那就直接删掉老的就成了;反之,要是新的和老的都有,但老的其实就是个假货并不是真的DOM元素,而且样子也差不多,这种情况下,diff算法就出来显示本领。
说起新老vue节点对不上号这个问题,那就得找找旧节点的’爹’,帮它搞个新孩子。修视图那会儿,大伙儿都是用patchVNode这个法子搞定的。咱们就一起来看看patchVNode到底是怎么回事!
var isRealElement = isDef(oldVnode.nodeType); if (!isRealElement && sameVnode(oldVnode, vnode)) { // patch existing root node patchVnode(oldVnode, vnode, insertedVnodeQueue, removeOnly); }
说白了,patchVnode这货儿就看新旧节点是不是一套脸谱就行,可别担心;但要是碰到那种不干正事的vnode节点,你得小心点儿了!要是这个vnode正好在搞文字秀,看到新旧元素的字变样了,赶紧给dom上的字儿换新车。
var oldElm = oldVnode.elm; var parentElm = nodeOps.parentNode(oldElm); // create new node createElm( vnode, insertedVnodeQueue, // extremely rare edge case: do not insert if old element is in a // leaving transition. Only happens when combining transition + // keep-alive + HOCs. (#4590) oldElm._leaveCb ? null : parentElm, nodeOps.nextSibling(oldElm) );
好了,来聊聊patchVnode。它新添了个“更新子元素”的功能,不过这个功能只能在新老vnode都是非文本类型的时候起作用。是不是觉得Vue渲染机制越来越厉害?
要搞定新旧vnode,就得靠updateChildren,超级简单易懂。先看看到底有没有vnode出现过,如果还没出现,那就再查查NEW vnode的孩子里有没有OLD vnode的关键词。找不到也没事儿,咱就新创建一个DOM节点;找到但是不相同?也不怕!用patchVnode就可以把它们俩都弄好。好了,今天就说到这儿,希望你们看过这篇文章之后对于Vue怎么通过虚拟dom渲染视图能了解更深点儿。要是还有啥想问的或者想讨论的事儿,欢迎随时留言给我们别忘了点个赞、分享给你的小伙伴们哈~
if (oldVnode === vnode) { return }
评论0