Bootstrap

【Vue2.x 源码学习】第十二篇 - 生成 ast 语法树-流程说明

一,前言

上篇,主要介绍了 vue 数据渲染核心流程,涉及以下几个点:

初次渲染时

视图更新时

本篇,生成 ast 语法树-流程说明

二,Vue 提供的使用方式

1,三种模板写法及优先级


  
  
{{message}}

三种写法的优先级【由高到低】:

  • 使用 render

  • 使用 template

  • 使用元素中的内容;即使用

    {{message}}
    中的 {{message}}

2,两种数据挂载方式

在 Vue2.x 中,提供了两种挂载方式:

let vm = new Vue({
  // el: '#app',		// 挂载方式一
  data() {
  },
}).$mount('#app');	// 挂载方式 2

当挂载点 vm.$options.el 存在,或直接调用了 Vue 的原型方法 $mount 时,

就会通过Vue 上的原型方法 $mount 对数据进行挂载操作

三,Vue 的原型方法 $mount


  
{{message}}

当 vm.$options.el 存在,或直接调用 Vue 的原型方法 $mount 时,就会对数据进行挂载操作;

所以,设置 vm.$options.el 或 .$mount,内部都是调用 Vue 原型方法 $mount 进行处理的;

在 $mount 中,拿到 el 挂载点指向的真实 dom 元素,并使用新内容将它替换掉

// src/init.js#initMixin

export function initMixin(Vue) {
  Vue.prototype._init = function (options) {
    const vm = this;
    vm.$options = options;
    
    initState(vm);

    if (vm.$options.el) {
      // 将数据挂载到页面上(此时数据已被观测)
      vm.$mount(vm.$options.el)
    }
  }

  // 支持 new Vue({el}) 和 new Vue().$mount 两种情况
  Vue.prototype.$mount = function (el) {
    const vm = this;
    el = document.querySelector(el); // 获取真实的元素
    vm.$el = el; // vm.$el 为当前页面上的真实元素
  }
}

如何拿到"id = app"对应的元素,outerHTML or innerHTML?

  • outerHTML:

    {{message}}

  • innerHTML:{{message}}

这里,由于需要使用的新内容替换掉老的内容,

所以,需要使用outerHTML拿到全部内容

再结合不同模板写法的优先级逻辑:

// src/init.js

Vue.prototype.$mount = function (el) {
  const vm = this;
  const opts = vm.$options;
  el = document.querySelector(el);
  vm.$el = el;

  // 如果没有 render, 找 template
  if (!opts.render) {
    // 如果没有 template, 采用元素中的内容
    const template = opts.template;
    if (!template) {
      // 拿到整个元素标签
      console.log(el.outerHTML);
    }
  }
}

运行查看结果:

四,将模板编译为 ast 语法树

1,compileToFunction

在 vue 中,编译阶段的最终结果是输出 render 函数:

//  src/compiler/index.js

export function compileToFunction(template) {
  // 1,将模板变成 AST 语法树
  let ast = parserHTML(template);
  // 2,使用 AST 生成 render 函数
  let code = generate(ast);
}

function parserHTML(template) {
  console.log("parserHTML-template : " + template)
}

function generate(ast) {
  console.log("parserHTML-ast : " + ast)
}

在 Vue 中,compileToFunction 方法是 Vue 编译的入口,

完成了以上两个操作,最终将模板编译成为 render 函数;

2,parserHTML

parserHTML 方法:将 HTML 模板编译成为 ast 语法树

注意:这里的 template 指的是