<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          vue中指令的編譯過(guò)程

          共 3983字,需瀏覽 8分鐘

           ·

          2021-09-15 23:21


          首先生成的 ast 會(huì)加上一些屬性,每個(gè) element 元素可以看作是一個(gè) ast 對(duì)象,整顆 DOM 樹(shù)可以看作是包含依賴(lài)關(guān)系的 ast 對(duì)象。

          v-if 指令

          源碼在 processIf(element) 函數(shù)里面處理

          // <span v-if="msg">6</span>// (msg)?_c('span',[_v("6")]):_e()let ast = [  {    type: 1,    tag: 'span',    attrsList: [],    attrsMap: { 'v-if': 'msg' },    rawAttrsMap: {},    parent: {      type: 1,      tag: 'div',      attrsList: [],      attrsMap: {},      rawAttrsMap: {},      parent: undefined,      children: [],      plain: true,      static: false,      staticRoot: false    },    children: [],    if: 'msg',    ifConditions: [ { exp: 'msg', block: el } ],    plain: true,    static: false,    staticRoot: false,    pre: undefined,    ifProcessed: true  }]


          先 processIf 再 genIf,生成 render:

          function genIf (  el,  state,  altGen,  altEmpty) {  el.ifProcessed = true; // avoid recursion  return genIfConditions(el.ifConditions.slice(), state, altGen, altEmpty)}
          function genIfConditions ( conditions, // [ { exp: 'msg', block: el } ] state, altGen, // 無(wú) altEmpty // 無(wú)) { if (!conditions.length) { return altEmpty || '_e()' }
          var condition = conditions.shift(); if (condition.exp) { // 主要看這里,通過(guò)三元運(yùn)算符?和:拼接字符串 return ("(" + (condition.exp) + ")?" + (genElement(el, state)) + ":" + (genIfConditions(conditions, state, altGen, altEmpty))) } else { return ("" + (genTernaryExp(condition.block))) }}

          v-for 指令

          源碼在 processFor(element) 函數(shù)里面處理

          // _l((list), function(item){return _c('span',[_v("6")])})// <span v-for="item in list">6</span>let ast = [  {    type: 1,    tag: 'span',    attrsList: [],    attrsMap: { 'v-for': 'item in list' },    rawAttrsMap: {},    parent: {      type: 1,      tag: 'div',      attrsList: [],      attrsMap: {},      rawAttrsMap: {},      parent: undefined,      children: [],      plain: true,      static: false,      staticRoot: false    },    children: [],    for: 'list',    alias: 'item',    plain: true,    static: false,    staticRoot: false,    pre: undefined,    forProcessed: true  }]


          我們簡(jiǎn)單想象一下 for 指令需要包裝成一個(gè)函數(shù),方便之后的循環(huán)遍歷,比如下面這樣:

          function _l(list, callback) { list.forEach(item => callback(item))  }


          具體的生成過(guò)程:

          function genFor (  el,  state,  altGen, // 無(wú)  altHelper // 無(wú)) {  var exp = el.for;  var alias = el.alias;  var iterator1 = el.iterator1 ? ("," + (el.iterator1)) : '';  var iterator2 = el.iterator2 ? ("," + (el.iterator2)) : '';  // 主要看這里,包裝成一個(gè)function函數(shù)  el.forProcessed = true; // avoid recursion  return ('_l') + "((" + exp + ")," +    "function(" + alias + iterator1 + iterator2 + "){" +      "return " + ((genElement)(el, state)) +    '})'}

          v-once 指令

          源碼在 processOnce(element) 函數(shù)里面處理

          // <div>11<span v-once="msg">6</span></div>// render: `with(this){return _c('div',[_v("11"),_m(0)])}`,// staticRenderFns: [ `with(this){return _c('span',[_v("6")])}` ],let ast = [  {    type: 1,    tag: 'span',    attrsList: [],    attrsMap: { 'v-once': '' },    rawAttrsMap: {},    parent: {      type: 1,      tag: 'div',      attrsList: [],      attrsMap: {},      rawAttrsMap: {},      parent: undefined,      children: [],      plain: true,      static: false,      staticRoot: false    },    children: [],    once: true,    plain: true,    static: false,    staticInFor: false,    staticRoot: false,    pre: undefined,    onceProcessed: true,    staticProcessed: true  }]


          v-once 只渲染元素和組件一次。隨后的重新渲染,元素/組件及其所有的子節(jié)點(diǎn)將被視為靜態(tài)內(nèi)容并跳過(guò)。這可以用于優(yōu)化更新性能。



          function genOnce (el, state) {  el.onceProcessed = true;  return genStatic(el, state)}
          function genStatic (el, state) { el.staticProcessed = true; var originalPreState = state.pre; state.staticRenderFns.push(("with(this){return " + (genElement(el, state)) + "}")); state.pre = originalPreState; return ("_m(" + (state.staticRenderFns.length - 1) + (el.staticInFor ? ',true' : '') + ")")}


          生成 render 函數(shù)的目的就是為了當(dāng)綁定的變量值發(fā)生改變的時(shí)候,可以重新執(zhí)行 render 函數(shù),最后生成真實(shí)的 DOM,其中_c 和 _v 等等這些輔助函數(shù)就是處理真實(shí) DOM 的函數(shù),關(guān)于 render 函數(shù)生成 DOM 我們之后再分析。


          瀏覽 55
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  午夜gogo | 精品热99 | 中文字幕无码视频在线观看 | 亚洲无码福利视频 | 国产精品久久久久久久久久久久久久 |