所有分类
  • 所有分类
  • 后端开发
Vue数据驱动揭秘:为何数据一换,view跟着动?

Vue数据驱动揭秘:为何数据一换,view跟着动?

在patchVnode部分又浮现了一个新的函数:updateChildren,是在新老vnode都不是文本节点时调用的,这里就是vue的渲染机制的核心这样进行了递归处理,组件层的更新就完成了。本文为看源码分析vue更新机制部分,省略了特殊场

亲爱哒朋友们,今天咱来聊聊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);
} 

Vue数据驱动揭秘:为何数据一换,view跟着动?

好,我们来聊聊这个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
}

原文链接:https://www.icz.com/technicalinformation/web/vue2/2024/03/11354.html,转载请注明出处~~~
0

评论0

请先
注意:请收藏好网址www.icz.com,防止失联!站内免费资源持续上传中…!赞助我们
显示验证码
没有账号?注册  忘记密码?