欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Vue使用虛擬dom進行渲染view的方法

 更新時間:2019年12月26日 14:24:35   作者:_記憶  
這篇文章主要介紹了Vue使用虛擬dom進行渲染view的方法,本文給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下

前提

vue版本:v2.5.17-beta.0

觸發(fā)render

vue在數(shù)據(jù)更新后會自動觸發(fā)view的render工作,其依賴于數(shù)據(jù)驅(qū)動;在數(shù)據(jù)驅(qū)動的工作下,每一個vue的data屬性都被監(jiān)聽,并且在set觸發(fā)時,派發(fā)事件,通知收集到的依賴,從而觸發(fā)對應(yīng)的操作,render工作就是其中的一個依賴,并且被每一個data屬性所收集,因此每一個data屬性改變后,都會觸發(fā)render。

vue更新監(jiān)聽

看一段代碼

// 來自mountComponent函數(shù)
updateComponent = function () {
 vm._update(vm._render(), hydrating);
};

new Watcher(vm, updateComponent, noop, {
 before: function before () {
 if (vm._isMounted) {
  callHook(vm, 'beforeUpdate');
 }
 }
}, true /* isRenderWatcher */);

updateComponent是更新組件的函數(shù),內(nèi)部調(diào)用vm._update,并且傳參vm._render();

  • vm._render()返回了什么?看源碼則得知返回了虛擬dom(VNode)
  • vm._update函數(shù)又做了什么事情?顧名思義,更新傳入的vnode
  • 什么時候觸發(fā)updateComponent函數(shù)?在任何vue的data屬性更改值都會觸發(fā)

更新view

閱讀_update函數(shù)得知,最終調(diào)用了vm.__patch__方法,最終找到為createPatchFunction方法的返回值

var patch = createPatchFunction({ nodeOps: nodeOps, modules: modules });

Vue.prototype.__patch__ = inBrowser ? patch : noop; 

接下來重點看createPatchFunction的返回函數(shù)patch.

如果新的vnode不存在,則注銷舊的vnode

if (isUndef(vnode)) {
 if (isDef(oldVnode)) { invokeDestroyHook(oldVnode); }
 return
}

如果舊的vnode不存在,則創(chuàng)建新的vnode

if (isUndef(oldVnode)) {
 // empty mount (likely as component), create new root element
 isInitialPatch = true;
 createElm(vnode, insertedVnodeQueue);
} 

如果以上不成立,則新的vnode和oldVnode都存在.如果oldVnode不是真實的dom,則為虛擬dom節(jié)點,并且新老vnode相似,則進行diff算法

var isRealElement = isDef(oldVnode.nodeType);
if (!isRealElement && sameVnode(oldVnode, vnode)) {
 // patch existing root node
 patchVnode(oldVnode, vnode, insertedVnodeQueue, removeOnly);
}

如果新老vnode不同,則拿到oldVnode的父節(jié)點,輔助創(chuàng)建vnode的新節(jié)點

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)
);

以上的步驟發(fā)現(xiàn),更新view時,重點進入到了patchVnode函數(shù),因此下面進入patchVnode的函數(shù)閱讀

如果新老node相等,則不做處理

if (oldVnode === vnode) {
 return
}

如果vnode不是文本節(jié)點則有幾種情況

if (isDef(oldCh) && isDef(ch)) {
 // 如果oldVnode和vnode的children都有值(組件層),并且不想等,則執(zhí)行更新children流程
 if (oldCh !== ch) { updateChildren(elm, oldCh, ch, insertedVnodeQueue, removeOnly); }
} else if (isDef(ch)) {
 // 如果vnode的children有值,如果當前dom有文本則清空,
 // 并將oldVnode的dom作為父節(jié)點,創(chuàng)建新vnode的children節(jié)點
 if (isDef(oldVnode.text)) { nodeOps.setTextContent(elm, ''); }
 addVnodes(elm, null, ch, 0, ch.length - 1, insertedVnodeQueue);
} else if (isDef(oldCh)) {
 // 如果oldVnode存在children,但是新的沒有,則刪除oldVnode的children的vnode
 removeVnodes(elm, oldCh, 0, oldCh.length - 1);
} else if (isDef(oldVnode.text)) {
 // 如果oldVnode有文本信息,則將dom的文本清空
 nodeOps.setTextContent(elm, '');
}

如果vnode是文本節(jié)點, 則當新老節(jié)點文本不同,將dom的文本更新成新vnode的文本

else if (oldVnode.text !== vnode.text) {
 nodeOps.setTextContent(elm, vnode.text);
} 

patchVnode函數(shù)處理的情況梳理一下則為:

  • 如果新老vnode相同,不作處理
  • 如果新vnode是文本節(jié)點,并且新老文本不同,將dom更新為vnode的文本
  • 如果新老vnode都有children,表示他們是組件層,則調(diào)用updateChildren去做組件層更新
  • 如果新vnode是組件層,oldVnode不是,則將當前dom添加新vnode組件的子元素
  • 如果oldVnode是組件層,新vnode不是,則操作dom,將oldVnode包含的子元素刪除
  • 如果新vnode是組件層,oldVnode是文本節(jié)點,則將dom的文本清空

在patchVnode部分又浮現(xiàn)了一個新的函數(shù):updateChildren,是在新老vnode都不是文本節(jié)點時調(diào)用的,這里就是vue的渲染機制的核心

updateChildren

updateChildren中將新老vnode的children進行的循環(huán)處理,每一次循環(huán)去判斷是否有相同的vnode,如果沒有則查找當前新vnode的子節(jié)點的key是否存在oldVnode的children中,如果不存在在這存在但已經(jīng)不相同則創(chuàng)建新的dom,否則,如果是新老節(jié)點相同,回調(diào)patchVnode函數(shù)去處理2個節(jié)點。 這樣進行了遞歸處理,組件層的更新就完成了。

結(jié)尾

本文為看源碼分析vue更新機制部分,省略了特殊場景的源碼分析,比如ssr、靜態(tài)組件等。

總結(jié)

以上所述是小編給大家介紹的Vue使用虛擬dom進行渲染view的方法,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
如果你覺得本文對你有幫助,歡迎轉(zhuǎn)載,煩請注明出處,謝謝!

相關(guān)文章

  • 詳解基于Vue,Nginx的前后端不分離部署教程

    詳解基于Vue,Nginx的前后端不分離部署教程

    這篇文章主要介紹了詳解基于Vue,Nginx的前后端不分離部署教程,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-12-12
  • vue實現(xiàn)簡單的日歷效果

    vue實現(xiàn)簡單的日歷效果

    這篇文章主要為大家詳細介紹了vue實現(xiàn)簡單的日歷效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-06-06
  • Vue項目全局配置微信分享思路詳解

    Vue項目全局配置微信分享思路詳解

    這篇文章給大家介紹了vue項目全局配置微信分享思路講解,使用vue作為框架,使用vux作為ui組件庫,具體內(nèi)容詳情大家跟隨腳本之家小編一起學習吧
    2018-05-05
  • Vue Router的懶加載路徑的解決方法

    Vue Router的懶加載路徑的解決方法

    這篇文章主要介紹了Vue Router的懶加載路徑的解決方法,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下
    2018-06-06
  • vue?實現(xiàn)手動分割日期

    vue?實現(xiàn)手動分割日期

    這篇文章主要介紹了vue?實現(xiàn)手動分割日期,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • Vue3中使用pnpm搭建monorepo開發(fā)環(huán)境

    Vue3中使用pnpm搭建monorepo開發(fā)環(huán)境

    這篇文章主要為大家介紹了Vue3中使用pnpm搭建monorepo開發(fā)環(huán)境示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-08-08
  • vant(ZanUi)結(jié)合async-validator實現(xiàn)表單驗證的方法

    vant(ZanUi)結(jié)合async-validator實現(xiàn)表單驗證的方法

    這篇文章主要介紹了vant(ZanUi)結(jié)合async-validator實現(xiàn)表單驗證的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-12-12
  • vue點擊自增和求和的實例代碼

    vue點擊自增和求和的實例代碼

    今天小編就為大家分享一篇vue點擊自增和求和的實例代碼,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-11-11
  • vue封裝第三方插件并發(fā)布到npm的方法

    vue封裝第三方插件并發(fā)布到npm的方法

    本篇文章主要介紹了vue封裝第三方插件并發(fā)布到npm的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-09-09
  • vue3+ant?design的form數(shù)組表單校驗方法

    vue3+ant?design的form數(shù)組表單校驗方法

    這篇文章主要介紹了vue3+ant?design的form數(shù)組表單,如何校驗,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2023-09-09

最新評論