国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Vue源碼解析:AST語法樹轉(zhuǎn)render函數(shù)

trilever / 644人閱讀

摘要:源碼解析這邊解析的是從樹轉(zhuǎn)換成函數(shù)部分的源碼,由于第一次提交的源碼這部分不全,故做了部分更新,代碼全在文件夾中。入口整個語法樹轉(zhuǎn)函數(shù)的起點是文件中的函數(shù)明顯看到,函數(shù)傳入?yún)?shù)為語法樹,內(nèi)部調(diào)用函數(shù)開始解析根節(jié)點容器節(jié)點。

通過對 Vue2.0 源碼閱讀,想寫一寫自己的理解,能力有限故從尤大佬2016.4.11第一次提交開始讀,準備陸續(xù)寫:

模版字符串轉(zhuǎn)AST語法樹

AST語法樹轉(zhuǎn)render函數(shù)

Vue雙向綁定原理

Vue虛擬dom比較原理

其中包含自己的理解和源碼的分析,盡量通俗易懂!由于是2.0的最早提交,所以和最新版本有很多差異、bug,后續(xù)將陸續(xù)補充,敬請諒解!包含中文注釋的Vue源碼已上傳...

開始

今天要說的代碼全在codegen文件夾中,在說實現(xiàn)原理前,還是先看個簡單的例子!

{{msg}}

上述類名為container的元素節(jié)點包含5個子節(jié)點(其中3個是換行文本節(jié)點),轉(zhuǎn)化成的AST語法樹:

AST語法樹轉(zhuǎn)的render函數(shù)長這樣:

function _render() {
  with (this) { 
    return __h__(
      "div", 
      {staticClass: "container"}, 
      [
        " ",
        __h__("span", {}, [String((msg))]),
        " ",
        __h__("button", {class: {active: isActive},on:{"click":handle}}, ["change msg"]),
        " "
      ]
    )
  };
}

可以的看出,render函數(shù)做的事情很簡單,就是把語法樹每個節(jié)點的指令進行解析。

看下render函數(shù),它是由with函數(shù)包裹(為了改變作用域),要用的時候直接_render.call(vm);另外就是__h__函數(shù),這個后面會說到,這個函數(shù)用于元素節(jié)點的解析,接收3個參數(shù):元素節(jié)點標簽名,節(jié)點數(shù)據(jù),子節(jié)點數(shù)據(jù)。這個函數(shù)最后返回的就是虛擬dom了,不過今天先不深究,先說如何生成這樣的render函數(shù),主要是v-if、v-forv-bind、v-on等指令的解析。

源碼解析

這邊解析的是從AST樹轉(zhuǎn)換成render函數(shù)部分的源碼,由于vue2.0第一次提交的源碼這部分不全,故做了部分更新,代碼全在codegen文件夾中。

入口

整個AST語法樹轉(zhuǎn)render函數(shù)的起點是index.js文件中的generate()函數(shù):

export function generate (ast) {
  const code = genElement(ast);
  return new Function (`with (this) { return ${code}}`);
}

明顯看到,generate()函數(shù)傳入?yún)?shù)為AST語法樹,內(nèi)部調(diào)用genElement()函數(shù)開始解析根節(jié)點(容器節(jié)點)。genElement()函數(shù)用于解析元素節(jié)點,它接收兩個參數(shù):AST對象節(jié)點標識(v-for的key),最后返回形如__h__("div", {}, [])的字符串,看一下內(nèi)部邏輯:

function genElement (el, key) {
  let exp;
  if (exp = getAndRemoveAttr(el, "v-for")) { // 解析v-for指令
    return genFor(el, exp);
  } else if (exp = getAndRemoveAttr(el, "v-if")) { // 解析v-if指令
    return genIf(el, exp, key);
  } else if (el.tag === "template") { // 解析子組件
    return genChildren(el);
  } else {
    return `__h__("${el.tag}", ${genData(el, key) }, ${genChildren(el)})`;
  }
}

genElement()函數(shù)內(nèi)部依次調(diào)用getAndRemoveAttr()函數(shù)判斷了v-for、v-if標簽是否存在,若存在則刪除并返回表達式;隨后判斷節(jié)點名為template就直接進入子節(jié)點解析;以上條件都不符合就返回__h__函數(shù)字符串,該字符串將使用到屬性解析和子節(jié)點解析。

function getAndRemoveAttr (el, attr) {
  let val;
  // 如果屬性存在,則從AST對象的attrs和attrsMap移除
  if (val = el.attrsMap[attr]) {
    el.attrsMap[attr] = null;
    for (let i = 0, l = el.attrs.length; i < l; i++) {
      if (el.attrs[i].name === attr) {
        el.attrs.splice(i, 1);
        break;
      }
    }
  }
  return val;
}
v-for 和 v-if 指令解析

讓我們先看看v-for的編譯:

function genFor (el, exp) {
  const inMatch = exp.match(/([a-zA-Z_][w]*)s+(?:in|of)s+(.*)/);
  if (!inMatch) {
    throw new Error("Invalid v-for expression: "+ exp);
  }
  const alias = inMatch[1].trim();
  exp = inMatch[2].trim();
  let key = getAndRemoveAttr(el, "track-by"); // 后面用 :key 代替了 track-by

  if (!key) {
    key ="undefined";
  } else if (key !== "$index") {
    key = alias + "["" + key + ""]";
  }

  return `(${exp}) && (${exp}).map(function (${alias}, $index) {return ${genElement(el, key)}})`;
}

該函數(shù)先進行正則匹配,如"item in items",將解析出別名(item)和表達式(items),再去看看當前節(jié)點是否含:key,如果有那就作為genElement()函數(shù)的參數(shù)解析子節(jié)點。舉個

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/53484.html

相關(guān)文章

  • Vue源碼解析AST語法樹轉(zhuǎn)render函數(shù)

    摘要:源碼解析這邊解析的是從樹轉(zhuǎn)換成函數(shù)部分的源碼,由于第一次提交的源碼這部分不全,故做了部分更新,代碼全在文件夾中。入口整個語法樹轉(zhuǎn)函數(shù)的起點是文件中的函數(shù)明顯看到,函數(shù)傳入?yún)?shù)為語法樹,內(nèi)部調(diào)用函數(shù)開始解析根節(jié)點容器節(jié)點。 通過對 Vue2.0 源碼閱讀,想寫一寫自己的理解,能力有限故從尤大佬2016.4.11第一次提交開始讀,準備陸續(xù)寫: 模版字符串轉(zhuǎn)AST語法樹 AST語法樹轉(zhuǎn)r...

    Karuru 評論0 收藏0
  • Vue源碼解析:模版字符串轉(zhuǎn)AST語法

    摘要:通過對源碼閱讀,想寫一寫自己的理解,能力有限故從尤大佬第一次提交開始讀,準備陸續(xù)寫模版字符串轉(zhuǎn)語法樹語法樹轉(zhuǎn)函數(shù)雙向綁定原理虛擬比較原理其中包含自己的理解和源碼的分析,盡量通俗易懂由于是的最早提交,所以和最新版本有很多差異,后續(xù)將陸續(xù)補充, 通過對 Vue2.0 源碼閱讀,想寫一寫自己的理解,能力有限故從尤大佬2016.4.11第一次提交開始讀,準備陸續(xù)寫: 模版字符串轉(zhuǎn)AST語法...

    chengjianhua 評論0 收藏0
  • Vue源碼解析:模版字符串轉(zhuǎn)AST語法

    摘要:通過對源碼閱讀,想寫一寫自己的理解,能力有限故從尤大佬第一次提交開始讀,準備陸續(xù)寫模版字符串轉(zhuǎn)語法樹語法樹轉(zhuǎn)函數(shù)雙向綁定原理虛擬比較原理其中包含自己的理解和源碼的分析,盡量通俗易懂由于是的最早提交,所以和最新版本有很多差異,后續(xù)將陸續(xù)補充, 通過對 Vue2.0 源碼閱讀,想寫一寫自己的理解,能力有限故從尤大佬2016.4.11第一次提交開始讀,準備陸續(xù)寫: 模版字符串轉(zhuǎn)AST語法...

    王偉廷 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<