Vue.js源碼分析(五)--update

_update

這個方法是幹什麼的呢,前面我們生成了vnode,下一步就是把vnode映射到真實的DOM節點上,這裏包含了初次渲染和後面的更新渲染,拿首次渲染爲例,整理參數之後會去調用vm.__patch__方法,接着會去判斷瀏覽器環境或node.js上,前者轉到patch函數的調用,後者返回一個空函數,因爲在服務端是不存在DOM的。

讓我們把目光轉到patch函數上,他是createPatchFunction函數返回的結果:

export const patch: Function = createPatchFunction({ nodeOps, modules })

看一下函數簽名,接受一個對象,前者是一些常見的DOM操作,後者則是對常見attributes的一些鉤子函數的處理。

在createPatchFunction中定義了很多輔助函數,最後返回的還是一個patch,回顧整個過程,其實是使用了柯里化的技巧,整個createPatchFunction過程使用到的一些函數都是與平臺強相關的,所以相當於把與平臺強相關的內容體取出來集成到了createPatchFunction之中,在patch中可以忽視平臺的差異化參數。

patch

略過一系列定義的函數,在800多行我們終於能看到patch的全貌:

  return function patch(oldVnode, vnode, hydrating, removeOnly) {
    ...
  }

由函數調用時:

vm.$el = vm.__patch__(vm.$el, vnode, hydrating, false /* removeOnly */);

第一個參數是真實的DOM,第二個則是之前的虛擬DOM,後面同樣是涉及服務端渲染,暫時捨棄,默認爲false。這是初始化的時候的調用,如果是更新過程,則調用如下:

vm.$el = vm.__patch__(prevVnode, vnode);

接着往下走,對於第一次渲染,會走到:

oldVnode = emptyNodeAt(oldVnode);

這裏其實就是把真實的DOM轉化爲vnode,接着便是最重要的把vnode掛載到document內部,這裏利用了createElm函數。

在createElm內部,我們又會遇到一個常見的錯誤:

warn(
  "Unknown custom element: <" +
    tag +
    "> - did you " +
    "register the component correctly? For recursive components, " +
    'make sure to provide the "name" option.',
  vnode.context
);

這裏即組件沒有註冊時會出現的錯誤。

接着我們會轉到一個很重要的邏輯,即創建真實的DOM節點:

      vnode.elm = vnode.ns
        ? nodeOps.createElementNS(vnode.ns, tag)
        : nodeOps.createElement(tag, vnode);
      setScope(vnode);

這裏根據有無namespace分成兩種,我們先看nodeOps.createElement,這其實就是我們用的dom的操作的簡單封裝,接着會走一個createChildren邏輯,即如果有子節點依次創建即可:

        createChildren(vnode, children, insertedVnodeQueue);

接着會使用:

        insert(parentElm, vnode.elm, refElm);

方法去在父節點添加子節點,同樣對於insert方法,也只是對原生DOM的簡單封裝,只不過會做一些平臺校驗之類的額外工作。

當然對於順序來說,還是先創建子節點,然後再去遞歸創建父節點,最終掛載到響應的位置。

destroy old

        if (isDef(parentElm)) {
          removeVnodes([oldVnode], 0, 0);
        } else if (isDef(oldVnode.tag)) {
          invokeDestroyHook(oldVnode);
        }

掛載成功還有最後一步,舉例來說,這裏我們會創建一個新的div id=app,而原來舊的div id=app的空姐的仍然存在,所以最後一步需要把舊的節點銷燬,這樣才走完了全部的數據驅動流程。

總結

數據驅動答題流程就這樣結束了,當然這裏至少簡單分析了初次掛載,後面會更加深入的介紹,總體來說收穫還是很大的,繼續加油

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章