教育行業(yè)A股IPO第一股(股票代碼 003032)

全國(guó)咨詢(xún)/投訴熱線:400-618-4000

Vue 的 template 是如何編譯成真正的 HTML

更新時(shí)間:2019年01月10日15時(shí)32分 來(lái)源:傳智播客 瀏覽次數(shù):

1. 首先第一步實(shí)例化一個(gè)vue項(xiàng)目
2. 模板編譯是在vue生命周期的mount階段進(jìn)行的
3. 在mount階段的時(shí)候執(zhí)行了compile方法將template里面的內(nèi)容轉(zhuǎn)化成真正的html代碼
4. parse階段是將html轉(zhuǎn)化成ast(抽象語(yǔ)法樹(shù)),用來(lái)表示代碼的數(shù)據(jù)結(jié)構(gòu)。在 Vue 中我把它理解為嵌套的、攜帶標(biāo)簽名、屬性和父子關(guān)系的 JS 對(duì)象,以樹(shù)來(lái)表現(xiàn) DOM 結(jié)構(gòu)。 
[JavaScript] 純文本查看 復(fù)制代碼
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
html: "<div id="test">texttext</div>"
    //html轉(zhuǎn)換成ast
    ast: {
    // 標(biāo)簽類(lèi)型
    type: 1,
    // 標(biāo)簽名
    tag: "div",
    // 標(biāo)簽行內(nèi)屬性列表
    attrsList: [{name: "id", value: "test"}],
    // 標(biāo)簽行內(nèi)屬性
    attrsMap: {id: "test"},
    // 標(biāo)簽關(guān)系 父親
    parent: undefined,
    // 字標(biāo)簽屬性列表
    children: [{
        type: 3,
        text: 'texttext'
      }
    ],
    plain: true,
    attrs: [{name: "id", value: "'test'"}]
  }

5. optimize 會(huì)對(duì)parse生成的ast樹(shù)進(jìn)行靜態(tài)資源優(yōu)化(靜態(tài)內(nèi)容指的是和數(shù)據(jù)沒(méi)有關(guān)系,不需要每次都刷新的內(nèi)容)
6. generate 函數(shù),會(huì)將每一個(gè)ast節(jié)點(diǎn)創(chuàng)建一個(gè)內(nèi)部調(diào)用的方法等待后面的調(diào)用。
[JavaScript] 純文本查看 復(fù)制代碼
1
2
3
4
5
6
7
8
9
<template>
  <div id="test">
    {{val}}
    <img src="http://xx.jpg">
  </div>
</template>
//最后輸出
{render: "with(this){return _c('div',{attrs:{"id":"test"}},[[_v(_s(val))]),_v(" "),_m(0)])}"}

7. 在complie過(guò)程結(jié)束之后會(huì)生成一個(gè)render字符串 ,接下來(lái)就是 new watcher這個(gè)時(shí)候會(huì)對(duì)綁定的數(shù)據(jù)執(zhí)行監(jiān)聽(tīng),render 函數(shù)就是數(shù)據(jù)監(jiān)聽(tīng)的回調(diào)所調(diào)用的,其結(jié)果便是重新生成 vnode。當(dāng)這個(gè) render 函數(shù)字符串在第一次 mount、或者綁定的數(shù)據(jù)更新的時(shí)候,都會(huì)被調(diào)用,生成 Vnode。如果是數(shù)據(jù)的更新,那么 Vnode 會(huì)與數(shù)據(jù)改變之前的 Vnode 做 diff,對(duì)內(nèi)容做改動(dòng)之后,就會(huì)更新到我們真正的 DOM 上啦 



作者:傳智播客前端與移動(dòng)開(kāi)發(fā)培訓(xùn)學(xué)院

首發(fā): http://web.itcast.cn

0 分享到:
和我們?cè)诰€交談!