關(guān)于一些Vue的文章。(6)

原文鏈接我的blog,歡迎STAR。

在上篇里,我們已經(jīng)分析了在 main.js 可以通過(guò)el屬性設(shè)置掛載點(diǎn),又可以通過(guò)手動(dòng)設(shè)置 vm.$mount()。在這篇,我們深入底層,了解原理。

老規(guī)矩,我們先分享一篇文章 Vue.js 源碼學(xué)習(xí)筆記

這篇文章里反復(fù)提到了compile, 額....(什么鬼?手動(dòng)攤手。)

Vue,官網(wǎng)文檔, 原來(lái)Vue模板編譯成render函數(shù)的過(guò)程叫做 compile。


現(xiàn)在入正題:

_init, 文件里,有一條重要的線索:

_init 的最后,會(huì)運(yùn)行 initRender 方法,在這個(gè)方法中,如果el屬性存在,既是運(yùn)行vm.$mount(vm.$options.el),掛載一個(gè)未掛載的實(shí)例。如果不存在,既是已經(jīng)通過(guò)vm.$mount()手動(dòng)地掛載一個(gè)未掛載的實(shí)例。

接下來(lái),我們找到 vm.$mount() 方法,

源碼上分析:

  // 如果options.render 存在,直接運(yùn)行mount方法
  // 如果不存在時(shí)
  if (!options.render) {
    let template = options.template
    
    // 如果template模板存在,獲取template參數(shù)作為模板
    if (template) {
      if (typeof template === 'string') {
        if (template.charAt(0) === '#') {
          template = idToTemplate(template)
          /* istanbul ignore if */
          if (process.env.NODE_ENV !== 'production' && !template) {
            warn(
              `Template element not found or is empty: ${options.template}`,
              this
            )
          }
        }
      } else if (template.nodeType) {
        template = template.innerHTML
      } else {
        if (process.env.NODE_ENV !== 'production') {
          warn('invalid template option:' + template, this)
        }
        return this
      }
    } else if (el) {
      // 如果template不存在,且el存在
      // 則獲取template的outHTML作為模板
      template = getOuterHTML(el)
    }
    
    // 如果template模板存在,則調(diào)用compileToFunctions, 轉(zhuǎn)化為render
    if (template) {
      /* istanbul ignore if */
      if (process.env.NODE_ENV !== 'production' && config.performance && mark) {
        mark('compile')
      }

      const { render, staticRenderFns } = compileToFunctions(template, {
        shouldDecodeNewlines,
        delimiters: options.delimiters
      }, this)
      options.render = render
      options.staticRenderFns = staticRenderFns

      /* istanbul ignore if */
      if (process.env.NODE_ENV !== 'production' && config.performance && mark) {
        mark('compile end')
        measure(`${this._name} compile`, 'compile', 'compile end')
      }
    }
  }
  return mount.call(this, el, hydrating)

從這段源碼里,我們也能夠很直觀的得到以前的一個(gè)結(jié)論,Vue 2.0中的模板有三種引用寫(xiě)法:el, template, render。其中的優(yōu)先級(jí)是 render > template > el。

當(dāng)完成 compileToFunctions() 將模板轉(zhuǎn)化為 render 以后,會(huì)開(kāi)始 mount 方法。

mount方法里,

    vm._watcher = new Watcher(vm, updateComponent, noop)
    updateComponent = () => {
      vm._update(vm._render(), hydrating)
    }

轉(zhuǎn)了一圈,其實(shí)又回到了從render函數(shù),返回 vnode 的部分,這里我們?cè)诘谌呀?jīng)詳解,不再重復(fù)。


完。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 這篇筆記主要包含 Vue 2 不同于 Vue 1 或者特有的內(nèi)容,還有我對(duì)于 Vue 1.0 印象不深的內(nèi)容。關(guān)于...
    云之外閱讀 5,177評(píng)論 0 29
  • 原文鏈接我的blog,歡迎STAR。 前三篇里,我們開(kāi)始從render, template, el的渲染DOM樹(shù)的...
    三毛丶閱讀 678評(píng)論 0 0
  • 世間好物不堅(jiān)牢,彩云易散琉璃。 從今往后,咱們只有死別,再無(wú)生離。 家在哪里,我不知道,我還在尋覓歸途。人世間不會(huì)...
    木子瀟湘閱讀 347評(píng)論 0 1
  • 戲臺(tái)上的人物,大都有自己的人設(shè),走規(guī)劃好的路線,說(shuō)設(shè)定好的臺(tái)詞,每天都是在被表演著的。 近來(lái)衙門(mén)有點(diǎn)忙,案子有點(diǎn)多...
    神奇小逗閱讀 348評(píng)論 0 0
  • 當(dāng)我們開(kāi)始回憶時(shí),我們就老了。 一 我小時(shí)候并無(wú)對(duì)城市的概念。出生是在一個(gè)距離縣城偏僻遙遠(yuǎn)的水泥廠,童年是在一個(gè)只...
    菜園子閱讀 2,693評(píng)論 0 5

友情鏈接更多精彩內(nèi)容