Vue2 x原始碼解讀 模板編譯

2021-10-20 20:12:39 字數 3462 閱讀 3520

模板編譯作用模板編譯入口

模板編譯的入口在$mount方法中,在處理使用者傳入的template時,會將使用者傳入的template轉化為render函式。在原始碼的src/platforms/web/entry-runtime-with-compiler.js檔案中定義了這個處理過程。

模板編譯的過程

$mount方法中會呼叫compiletofunctions方法將template轉化為renderstaticrenderfns

compiletofunctions方法中主要會經過一下幾個過程:

function

compiletofunctions

( template: string,

options?

: compileroptions,

vm?: component

): compiledfunctionresult

, options)

const warn = options.warn || basewarn

delete options.warn

/* istanbul ignore if */

if(process.env.

node_env

!=='production'

)catch(e

)}}// check cache

// 1. 讀取快取中的 compiledfunctionresult 物件,如果有直接返回

const key = options.delimiters

?string

(options.delimiters)

+ template

: template

if(cache[key]

)// compile

// 2. 把模板編譯為編譯物件(render, staticrenderfns),字串形式的js**

const compiled =

compile

(template, options)

// check compilation errors/tips

if(process.env.

node_env

!=='production'

)\n\n`

+generatecodeframe

(template, e.start, e.end)

, vm

)})}else

\n\n`

+ compiled.errors.

map(e =>

`- $`)

.join

('\n')+

'\n'

, vm

)}}if(compiled.tips && compiled.tips.length)

else}}

// turn code into functions

const res =

const fngenerrors =

// 3. 把字串形式的js**轉換成js方法

res.render =

createfunction

(compiled.render, fngenerrors)

res.staticrenderfns = compiled.staticrenderfns.

map(code =>

)// check function generation errors.

// mostly for codegen development use

/* istanbul ignore if */

if(process.env.

node_env

!=='production'))

=>`$

in\n\n

$\n`).

join

('\n'),

vm)}}

// 4. 快取並返回res物件(render, staticrenderfns方法)

return

(cache[key]

= res)

}

嘗試從快取中讀取編譯結果,如果能夠成功讀取,則直接返回。

呼叫生成compiletofunctions方法時傳入的compile方法將模板編譯成物件。

將字串形式的js**通過new function轉化成方法。

快取並返回包含renderstaticrenderfns屬性的物件。

compile方法是將template轉化為物件,其內部核心是呼叫傳入的basecompile完成轉化,並將過程中收集的告警和錯誤存入到物件中。

basecompile的實現過程:

function

basecompile

( template: string,

options: compileroptions

): compiledresult

// 把抽象語法樹生成字串形式的 js **

const code =

generate

(ast, options)

return

}

優化抽象語法樹。抽象語法樹的優化主要是標記靜態節點和靜態根節點。重新渲染時會忽略這兩種節點,因為是靜態的,不會發生改變。

靜態節點:文字節點,或者沒有bind、不是v-if/v-for/v-else、不是build-in內建元件、不是元件不是v-for下的直接子節點。 節點存乙個非靜態子節點,則該節點不是靜態節點。

靜態根節點:節點是靜態節點,且其自己子節點不能是有且只有乙個文字節點。

呼叫generate方法根據抽象語法樹生成字串形式的js**code物件,code物件中包含renderstaticrenderfns方法。

返回包含astrenderstaticrenderfns屬性的物件。

vue2 x原始碼導讀

src platforms web entry runtime with compiler.js src platforms web runtime index.js src core index.js src core instance index.js 建構函式的定義 function vue ...

Vue2 x 原始碼閱讀筆記

定義 vue 的 init 方法 初始化 vm.options 初始化生命週期 初始化 events 初始化 render 呼叫鉤子函式 beforecreate 初始化 injections 初始化 state 初始化 methods 初始化 data 初始化 computed 初始化 watch...

Vue2 x之迴圈模板指令

v for指令用於遍歷陣列,物件很方便。在兩者遍歷時,我們都使用了 key指令,這是在標識區別每一項,避免vue渲染錯誤。但在實際使用中遇到情況更多是需要多元素配合的。假如我們想連續使用多個li標籤和hr標籤,可採用以下語法 v for標籤繫結的元素中的內容會被遍歷多次 但是這樣使用會多出乙個冗餘標...