关于一些Vue的文章。(6)

原文链接我的blog,欢迎STAR。

在上篇里,我们已经分析了在 main.js 可以通过el属性设置挂载点,又可以通过手动设置 vm.$mount()。在这篇,我们深入底层,了解原理。

老规矩,我们先分享一篇文章 Vue.js 源码学习笔记

这篇文章里反复提到了compile, 额....(什么鬼?手动摊手。)

Vue,官网文档, 原来Vue模板编译成render函数的过程叫做 compile


现在入正题:

_init, 文件里,有一条重要的线索:

_init 的最后,会运行 initRender 方法,在这个方法中,如果el属性存在,既是运行vm.$mount(vm.$options.el),挂载一个未挂载的实例。如果不存在,既是已经通过vm.$mount()手动地挂载一个未挂载的实例。

接下来,我们找到 vm.$mount() 方法,

源码上分析:

  // 如果options.render 存在,直接运行mount方法
  // 如果不存在时
  if (!options.render) {
    let template = options.template
    
    // 如果template模板存在,获取template参数作为模板
    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模板存在,则调用compileToFunctions, 转化为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)

从这段源码里,我们也能够很直观的得到以前的一个结论,Vue 2.0中的模板有三种引用写法:el, template, render。其中的优先级是 render > template > el

当完成 compileToFunctions() 将模板转化为 render 以后,会开始 mount 方法。

mount方法里,

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

转了一圈,其实又回到了从render函数,返回 vnode 的部分,这里我们在第三篇已经详解,不再重复。


完。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 这篇笔记主要包含 Vue 2 不同于 Vue 1 或者特有的内容,还有我对于 Vue 1.0 印象不深的内容。关于...
    云之外阅读 5,204评论 0 29
  • 原文链接我的blog,欢迎STAR。 前三篇里,我们开始从render, template, el的渲染DOM树的...
    三毛丶阅读 699评论 0 0
  • 世间好物不坚牢,彩云易散琉璃。 从今往后,咱们只有死别,再无生离。 家在哪里,我不知道,我还在寻觅归途。人世间不会...
    木子潇湘阅读 358评论 0 1
  • 戏台上的人物,大都有自己的人设,走规划好的路线,说设定好的台词,每天都是在被表演着的。 近来衙门有点忙,案子有点多...
    神奇小逗阅读 377评论 0 0
  • 当我们开始回忆时,我们就老了。 一 我小时候并无对城市的概念。出生是在一个距离县城偏僻遥远的水泥厂,童年是在一个只...
    菜園子阅读 2,724评论 0 5

友情链接更多精彩内容