<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                [TOC] >[success] # 分析init 中的 -- patch ~~~ 1.patch 主要做把vnode渲染成真實dom,并返回vnode 1.1.傳入新舊 VNode,對比差異,把差異渲染到 DOM 1.2.返回新的 VNode,作為下一次 patch() 的 oldVnode 2.執行過程: 2.1.首先執行模塊中的鉤子函數 pre 2.2.如果 oldVnode 和 vnode 相同(key 和 sel 相同) 2.2.1.調用 patchVnode(),找節點的差異并更新 DOM 2.3.如果 oldVnode 是 DOM 元素 2.3.1.把 DOM 元素轉換成 oldVnode 2.3.2.調用 createElm() 把 vnode 轉換為真實 DOM,記錄到 vnode.elm 2.3.3.把剛創建的 DOM 元素插入到 parent 中 2.3.4.移除老節點 2.3.5.觸發用戶設置的 create 鉤子函數 3.整個新老虛擬dom的比較在這里分為兩種情況,一種情況是新老node 的key 和sel相同,認為他是內部 子元素變化了或者標簽屬性變化了,一種是新老虛擬dom的key 和sel 完全不同,認為他是整體替換了 4.第一種情況會直接走'patchVnode()' 后續來分析這個方法 5.第二種情況先對 '2.3.1'進行分析 一般在最開始的時候,沒有所謂的老的虛擬dom,我們可能是指定一個 dom,然后這個dom位置是我們要替換的虛擬dom例如: let app = document.querySelector('#app') let oldVnode = patch(app, vnode) 這里還會發現會找到老的虛擬dom的父節點,因為我們是新老虛擬dom的替換,因此這個新老虛擬dom父節點 肯定是一個,我們只要吧新的插入這個父節點,在吧原來的老的虛擬dom刪除即可,因此下面邏輯也是這么做的 這種情況里'createElm' 就是將虛擬dom創建成dom的方法后續分析 6.總結:'patch' 方法是比較新老虛擬dom,因此如果傳入的是真實dom通過'emptyNodeAt'將其構造為 空的虛擬dom,這里回顧一下'Vnode'結構'sel,data,children,text,elm'所謂的空虛擬dom就是'data,children,text' 這些默認控制,但是sel關閉標簽是可以獲取因此需要對應轉換,elm記錄的就是真實dom,因此直接賦值, 所以在看'emptyNodeAt' 方法就很好理解 function emptyNodeAt (elm: Element) { const id = elm.id ? '#' + elm.id : '' const c = elm.className ? '.' + elm.className.split(' ').join('.') : '' return vnode(api.tagName(elm).toLowerCase() + id + c, {}, [], undefined, elm) } 當將這些傳入的是真實dom結構轉換為虛擬dom時候,就可以進行新老虛擬dom的比較,這個比較的過程使用 的是'key' 和'sel'如果新老虛擬dom 二者屬性相同就可以認為整個dom可以復用只需'找節點的差異并更新 DOM' ,如果不同認為整個新老dom已經產生了大的更新,需要找到老虛擬dom的'父節點',將新的dom插入 '老虛擬dom的父節點中'刪除老的虛擬dom對應的真實dom,這樣新老dom就完成替換 ~~~ >[danger] ##### 代碼 ~~~ // init 內部返回 patch函數,把vnode渲染成真實dom,并返回vnode // 不需要額外傳遞modules domapi return function patch(oldVnode: VNode | Element, vnode: VNode): VNode { let i: number, elm: Node, parent: Node; // 保存新插入節點的隊列,為了觸發鉤子函數 const insertedVnodeQueue: VNodeQueue = []; // 執行模塊的 pre 鉤子函數 for (i = 0; i < cbs.pre.length; ++i) cbs.pre[i](); // 如果 oldVnode 不是 VNode,創建 VNode 并設置 elm if (!isVnode(oldVnode)) { // 把 DOM 元素轉換成空的 VNode oldVnode = emptyNodeAt(oldVnode); } // 如果新舊節點是相同節點(key 和 sel 相同) if (sameVnode(oldVnode, vnode)) { // 找節點的差異并更新 DOM patchVnode(oldVnode, vnode, insertedVnodeQueue); } else { // 如果新舊節點不同,vnode 創建對應的 DOM // 獲取當前的 DOM 元素 elm = oldVnode.elm!; parent = api.parentNode(elm); // 觸發 init/create 鉤子函數,創建 DOM createElm(vnode, insertedVnodeQueue); if (parent !== null) { // 如果父節點不為空,把 vnode 對應的 DOM 插入到文檔中 api.insertBefore(parent, vnode.elm!, api.nextSibling(elm)); // 移除老節點 removeVnodes(parent, [oldVnode], 0, 0); } } // 執行用戶設置的 insert 鉤子函數 for (i = 0; i < insertedVnodeQueue.length; ++i) { insertedVnodeQueue[i].data!.hook!.insert!(insertedVnodeQueue[i]); } // 執行模塊的 post 鉤子函數 for (i = 0; i < cbs.post.length; ++i) cbs.post[i](); // 返回 vnode return vnode; }; ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看