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

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                >[success] # 分析snabbdom 源碼h函數 ~~~ 1.先從分析 h 函數,如何創建虛擬節點 ~~~ >[info] ## 分析這段代碼 ~~~ 1.h創建虛擬節點(vnodes)。h函數第一個參數'字符串形式的標簽/選擇器'、 第二個參數'一個可選的數據對象'、第三個參數'一個可選的字符串或數組作為子代' 2.先看一下,h函數在使用的時候傳參的幾種使用方法: 1.1. 一個參數h('div#container.cls') 創建一個div標簽 id是container,class是cls/也可以直接是一個選擇器 1.2.第二個參數類型可以使用,'VNodeData','VNodeChildren'這兩種類型對象, 這里可以這么理解'VNodeData'是給你設置的標簽屬于一些屬性,例如點擊事件,樣式等,'VNodeChildren' 是設置標簽內部一些子元素(VNodeChildren 的類型可以是VNode | string | number | undefined | null 或這些類型數組) 1.3.三個參數的時候就是可以創建一個完整的這種形式: "<div id='container' class='cls' style='color:red'>我是例子<span>例子<span></div>" 2.看一個完整的版的 傳參例子(這個例子中第二個參數類型就是VNodeData,第三個參數類型VNodeChildren) let vnode = h('div', { style: { backgroundColor: 'red' }, on: { click: eventHandler } }, [ '我是文本' h('h1', 'Hello Snabbdom'), h('p', '這是p標簽') ]) ~~~ >[danger] ##### 分析代碼 -- src/h.ts ~~~js 1.首先明確'JavaScript 中沒有重載的概念','TypeScript 中有重載,不過重載的實現還是通過代碼調整參數', 可以理解為'通過規定了不同參數個數的時,參數的類型就是重載',Snabbdom是ts 編寫的 2.參數重載這里的分析: 2.1.一個參數的時候是一個字符串 2.2.第二個參數可以能是'VNodeData'類型,或者是'VNodeChildren' 類型 2.3.三個參數,依次分別是'字符串','VNodeData' ,'VNodeChildren' 類型 3.VNodeData類型定義如下: export interface VNodeData { props?: Props; attrs?: Attrs; class?: Classes; style?: VNodeStyle; dataset?: Dataset; on?: On; hero?: Hero; attachData?: AttachData; hook?: Hooks; key?: Key; ns?: string; // for SVGs fn?: () => VNode; // for thunks args?: Array<any>; // for thunks [key: string]: any; // for any other 3rd party module } 4.VNodeChildren類型定義: export type VNodeChildElement = VNode | string | number | undefined | null; export type ArrayOrElement<T> = T | T[]; export type VNodeChildren = ArrayOrElement<VNodeChildElement> 4.1.這里簡單對'VNodeChildElement'分析他可以是'VNode | string | number | undefined | null' 這些類型或這類型數組,這里說明一下'VNode'類型是h函數的返回類型,因此可以說就是 另外一個h函數 ~~~ * snabbdom 用過ts 重載可以限制不同參數個數時候對應參數類型 ~~~ export function h(sel: string): VNode; export function h(sel: string, data: VNodeData): VNode; export function h(sel: string, children: VNodeChildren): VNode; export function h(sel: string, data: VNodeData, children: VNodeChildren): VNode; export function h(sel: any, b?: any, c?: any): VNode {.....} ~~~ >[danger] ##### VNode -- src\package\vnode.ts ~~~ 1.'h()' 函數返回虛擬dom,在'src\package\vnode.ts' snabbdom對虛擬dom定義對象屬性分別有 1.1.'sel '選擇器 1.2.'data' 節點數據:屬性/樣式/事件等 類型VNodeData|undefined 1.3.'children'子節點類型 Array < VNode | string > | undefined 1.4.'elm'記錄 vnode 對應的真實 DOM 1.5.'text'節點中的內容,和 children 只能互斥 1.6.'key' 做優化 2.在來看'h()'函數傳入的參數'sel: string, data: VNodeData, children: VNodeChildren',可以理解成'h()'函數 將對應傳入參數,進行判斷重新分配到'vnode' 對應對象位置上 ~~~ ~~~js export interface VNode { // 選擇器 sel: string | undefined; // 節點數據:屬性/樣式/事件等 data: VNodeData | undefined; // 子節點,和 text 只能互斥 children: Array < VNode | string > | undefined; // 記錄 vnode 對應的真實 DOM elm: Node | undefined; // 節點中的內容,和 children 只能互斥 text: string | undefined; // 優化用 key: Key | undefined; } export function vnode(sel: string | undefined, data: any | undefined, children: Array < VNode | string > | undefined, text: string | undefined, elm: Element | Text | undefined): VNode { let key = data === undefined ? undefined : data.key; return { sel, data, children, text, elm, key }; } export default vnode; ~~~ >[danger] ##### src/h.ts 源碼 ~~~ 1.'h()'函數最終返回的是'vnode'對象,因為'h()' 函數傳入的參數不是固定的,可以理解'h()' 函數主要 做的就是將使用時候不固定的參數進行分配,匹配其要對應的'vnode對象key上' 2.因此下面'snabdom 中 h()函數'的代碼主要就是針對參數個數不同做了同的判斷處理和賦值 3.這里對處理 children 中的原始值(string/number)這里做個說明: [ '我是文本' h('h1', 'Hello Snabbdom'), h('p', '這是p標簽') ] 如果children 數組中有string 或者number 由于他們不是 h函數,因此想把這類東西后續轉換成 虛擬dom就需要先包裝成h函數 4.分析一個案例 h('div', { style: { backgroundColor: 'red' }, on: { click: eventHandler } }, [ h('h1', h('p', '這是p標簽')), h('p', '這是p標簽') ]) 注意這里h('h1', h('p', '這是p標簽')),嵌套形式的情況下,下面代碼也沒有遞歸是,是如果鋪平運行? 注意h 是一個函數現在嵌套的" h('p', '這是p標簽')" 是一個參數,此時代碼會先執行這個作為參數執行函數 返回'Vnode' 對象,代碼變成了h('h1',Vnode) 上面分析過第二個參數可以是'Vnode' ~~~ * [這一段帶注釋的代碼來源](https://github.com/lagoufed/vuejs-enhancement) ~~~ export function h(sel: any, b ? : any, c ? : any): VNode { var data: VNodeData = {}, children: any, text: any, i: number; // 處理參數,實現重載的機制 if (c !== undefined) { // 處理三個參數的情況 // sel、data、children/text if (b !== null) { data = b; } if (is.array(c)) { children = c; } // 如果 c 是字符串或者數字 else if (is.primitive(c)) { text = c; } // 如果 c 是 VNode else if (c && c.sel) { children = [c]; } } else if (b !== undefined && b !== null) { // 處理兩個參數的情況 // 如果 b 是數組 if (is.array(b)) { children = b; } // 如果 b 是字符串或者數字 else if (is.primitive(b)) { text = b; } // 如果 b 是 VNode else if (b && b.sel) { children = [b]; } else { data = b; } } if (children !== undefined) { // 處理 children 中的原始值(string/number) for (i = 0; i < children.length; ++i) { // 如果 child 是 string/number,創建文本節點 // 因為你的文本節點是'我是文本'類似這種在數組中不是一個h函數的 // 表現形式因此需要被轉換成一個h函數的表現形式 if (is.primitive(children[i])) children[i] = vnode(undefined, undefined, undefined, children[i], undefined); } } if ( sel[0] === 's' && sel[1] === 'v' && sel[2] === 'g' && (sel.length === 3 || sel[3] === '.' || sel[3] === '#') ) { // 如果是 svg,添加命名空間 addNS(data, children, sel); } // 返回 VNode return vnode(sel, data, children, text, undefined); }; // 導出模塊 export default h; ~~~
                  <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>

                              哎呀哎呀视频在线观看