<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.js 編譯模板的過(guò)程

          共 3017字,需瀏覽 7分鐘

           ·

          2023-08-22 11:48


          Vue.js 編譯模板的過(guò)程主要分為兩個(gè)階段:解析(Parse)和生成(Generate)。


          1、解析階段:這個(gè)階段的主要任務(wù)是將模板字符串轉(zhuǎn)換為抽象語(yǔ)法樹(AST)。抽象語(yǔ)法樹是一種以樹狀的形式表現(xiàn)源代碼結(jié)構(gòu)的模型。在 Vue.js 中,解析器會(huì)將模板字符串解析為一棵 AST,每個(gè)節(jié)點(diǎn)都是一個(gè)普通的 JavaScript 對(duì)象,這個(gè)對(duì)象描述了元素/文本節(jié)點(diǎn)的各種屬性。


          2、生成階段:這個(gè)階段的主要任務(wù)是將 AST 轉(zhuǎn)換為渲染函數(shù)。渲染函數(shù)的主要任務(wù)是將模板轉(zhuǎn)換為 Virtual DOM,也就是說(shuō),渲染函數(shù)的返回值是 Virtual DOM。


          這個(gè)過(guò)程的主要步驟如下:

          1、Vue 接收到模板字符串。

          2、Vue 使用解析器(Parser)將模板字符串解析為 AST。

          3、Vue 使用優(yōu)化器(Optimizer)標(biāo)記靜態(tài)節(jié)點(diǎn)。這個(gè)步驟不是必須的,但是它可以提高后續(xù)的 patch 過(guò)程。

          4、Vue 使用代碼生成器(Code Generator)將 AST 轉(zhuǎn)換為渲染函數(shù)。


          這個(gè)過(guò)程是 Vue.js 的編譯設(shè)計(jì)的精髓,它使得 Vue.js 可以提供類似于原生 JavaScript 的性能,同時(shí)還能提供一個(gè)簡(jiǎn)單易用的模板語(yǔ)法。


          vue-template-compiler是編譯vue模板的包,傳入模板返回AST抽象語(yǔ)法樹。

          const compiler = require('vue-template-compiler')
          const val = compiler.compile('<span class="active" :total="count">666</span>')


          輸出結(jié)果如下:

          const res = {  ast: {    type: 1,    tag: 'span',    attrsList: [ { name: 'total', value: 'count' } ],    attrsMap: { class: 'active', ':total': 'count' },    rawAttrsMap: {},    parent: undefined,    children: [ { type: 3, text: 666, static: true } ],    plain: false,    staticClass: '"active"',    hasBindings: true,    attrs: [ { name: 'total', value: 'count', dynamic: false } ],    static: false,    staticRoot: false  },  render: `with(this){return _c('span',{staticClass:"active",attrs:{"total":count}},[_v("666")])}`,  staticRenderFns: [],  errors: [],  tips: []}


          可以看到對(duì)象中有ast屬性和render函數(shù),其實(shí)ast是為了生成render函數(shù)用的。

          with (this) {  return _c(    'span',    { staticClass: "active", attrs: { "total": count } },    [_v("666")]  )}


          render函數(shù)會(huì)調(diào)用很多輔助的函數(shù),例如 _c,_v 那么這些都來(lái)自哪里呢?


          其實(shí)是渲染時(shí)候用的的輔助函數(shù),源碼路徑 https://github.com/vuejs/vue/blob/dev/src/core/instance/render-helpers/index.js

          export function installRenderHelpers (target: any) { target._o = markOnce target._n = toNumber target._s = toString target._l = renderList target._t = renderSlot target._q = looseEqual target._i = looseIndexOf target._m = renderStatic target._f = resolveFilter target._k = checkKeyCodes target._b = bindObjectProps target._v = createTextVNode target._e = createEmptyVNode target._u = resolveScopedSlots target._g = bindObjectListeners target._d = bindDynamicKeys target._p = prependModifier}


          發(fā)現(xiàn)上面并沒有_c,我們繼續(xù)尋找源碼可以發(fā)現(xiàn)在 initRender 這里,路徑 https://github.com/vuejs/vue/blob/dev/src/core/instance/render.js

          vm._c = (a, b, c, d) => createElement(vm, a, b, c, d, false)


          createElement 就是創(chuàng)建虛擬節(jié)點(diǎn) VNode。路徑 https://github.com/vuejs/vue/blob/dev/src/core/vdom/create-element.js


          那么至此,我們大致了解了 createElement 創(chuàng)建 VNode 的過(guò)程,每個(gè) VNode 有 children,children 每個(gè)元素也是一個(gè) VNode,這樣就形成了一個(gè) VNode Tree,它很好的描述了我們的 DOM Tree。

          瀏覽 156
          點(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>
                  操熟女| 男女嗯嗯嗯视频网站 | seseav| 大鸡巴操逼高潮视频 | 五月天电影三级片 |