上一节获取到了DOM树的字符串,准备进入compile阶段:

    //Line-9326functioncompileToFunctions(template,options,vm) {//获取配置参数options = options ||{};//...//Go!var compiled =compile(template, options);//...}

  该函数接受两个参数,DOM树字符串、配置参数,如图:,进函数:

//Line-9287functioncompile(template, options) {var finalOptions =Object.create(baseOptions);var errors =[];var tips =[];finalOptions.warn= function(msg, tip$$1) {(tip$$1 ?tips : errors).push(msg);};//合并参数if(options) {if(options.modules) {finalOptions.modules= (baseOptions.modules ||[]).concat(options.modules);}if(options.directives) {finalOptions.directives=extend(Object.create(baseOptions.directives),options.directives);}for (var key inoptions) {if (key !== 'modules' && key !== 'directives') {finalOptions[key]=options[key];}}}//核心编译函数var compiled =baseCompile(template, finalOptions);errors.push.apply(errors, detectErrors(compiled.ast));//提示与报错属性添加compiled.errors =errors;compiled.tips=tips;returncompiled}

  compile主要做了3件事:

  1、参数合并

  这里涉及到baseOptions与传进来的options,baseOptions是内置对象,与options合并后得到finalOptions作为参数传进第二步的函数。

    //Line-9529var baseOptions ={expectHTML:true,modules: modules$1,directives: directives$1,isPreTag: isPreTag,isUnaryTag: isUnaryTag,mustUseProp: mustUseProp,canBeLeftOpenTag: canBeLeftOpenTag,isReservedTag: isReservedTag,getTagNamespace: getTagNamespace,staticKeys: genStaticKeys(modules$1)};

  这个对象十分复杂,涉及的时候再做讲解。

  2、调用baseCompile函数

  该函数接受2个参数:字符串、参数对象。

    //Line-9261functionbaseCompile(template, options) {//解析字符串为ASTvar ast =parse(template.trim(), options);//优化
optimize(ast, options);// var code =generate(ast, options);return{ast: ast,render: code.render,staticRenderFns: code.staticRenderFns}}

  简单看一眼这个函数,3个调用都很简单暴力,后面一个一个讲解。

  3、添加提示、报错属性并返回compiled值

  将过程中出现的error与tips作为属性添加到compiled对象上,以便一次性输出。

  跑流程的话,主要还是看第二步,理一理DOM树字符串是如何被解析和编译的,来看parse这个函数吧! 

  这函数太长了,分两部分来: 

    //Line-7982functionparse(template, options) {//参数修正warn$2 = options.warn ||baseWarn;//这几个属性都是原型链上面的platformGetTagNamespace = options.getTagNamespace ||no;platformMustUseProp= options.mustUseProp ||no;platformIsPreTag= options.isPreTag ||no;preTransforms= pluckModuleFunction(options.modules, 'preTransformNode');transforms= pluckModuleFunction(options.modules, 'transformNode');postTransforms= pluckModuleFunction(options.modules, 'postTransformNode');//这是自家的 值为undefined…delimiters =options.delimiters;//变量声明var stack =[];var preserveWhitespace = options.preserveWhitespace !== false;varroot;varcurrentParent;var inVPre = false;var inPre = false;var warned = false;//功能函数functionwarnOnce(msg) {if (!warned) {warned= true;warn$2(msg);}}functionendPre(element) {if(element.pre) {inVPre= false;}if(platformIsPreTag(element.tag)) {inPre= false;}}parseHTML(/*...*/);returnroot}

  首先是获取options参数的属性,其中大部分都是定义在原型上,即baseOptions,所以没什么讲的。唯一涉及的函数就是pluckModuleFunction,比较简单,看一下内容:

    //Line-5684functionpluckModuleFunction(modules, key) {//返回modules[key]组成的数组return modules ?modules.map(function(m) {returnm[key];}).filter(function(_) {return_;}) : []}

  简而言之,就是返回一个数组,内容是modules[key],这里返回空数组。

  第一部分没什么讲的,主要是声明一些变量,第二部分才是核心:

    //Line-7982functionparse(template, options) {//...part-1
parseHTML(template, {warn: warn$2,expectHTML: options.expectHTML,isUnaryTag: options.isUnaryTag,canBeLeftOpenTag: options.canBeLeftOpenTag,shouldDecodeNewlines: options.shouldDecodeNewlines,start:functionstart(tag, attrs, unary) {/*code...*/},end:functionend() {/*code...*/},chars:functionchars(text) {/*code...*/}});returnroot}

  这部分就是巨大的函数调用,第一个参数为DOM字符串,第二个参数是一个对象,包含多个属性与方法,属性内容如下:

    //Line-7578//自闭合标签var isUnaryTag =makeMap('area,base,br,col,embed,frame,hr,img,input,isindex,keygen,' +'link,meta,param,source,track,wbr');//可以省略闭合标签var canBeLeftOpenTag =makeMap('colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr,source');//当前浏览器是否会对换行转义var shouldDecodeNewlines = inBrowser ? shouldDecode('\n', '&#10;') : false;functionshouldDecode(content, encoded) {var div = document.createElement('div');div.innerHTML= "<div a=\"" + content + "\">";return div.innerHTML.indexOf(encoded) > 0}

  第一个expectHTML在baseOptions中是默认true的,其余几个是标签名数组与换行转义判断的集合。

  剩余三个方法包括start、end、chars,单独讲不好讲,在parseHTML方法边跑边说。

  暂时结束,parseHTML方法非常长,单独讲。

转载于:https://www.cnblogs.com/QH-Jimmy/p/6905272.html

.6-Vue源码之AST(2)相关推荐

  1. 什么是php的ast结构,什么是AST?Vue源码中AST语法树的解析

    这篇文章给大家介绍的内容是关于什么是AST?Vue源码中AST语法树的解析,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 什么是AST AST是指抽象语法树(abstract syn ...

  2. Vue源码解析之Template转化为AST的实现方法

    什么是AST 在Vue的mount过程中,template会被编译成AST语法树,AST是指抽象语法树(abstract syntax tree或者缩写为AST),或者语法树(syntax tree) ...

  3. vue实例没有挂载到html上,vue 源码学习 - 实例挂载

    前言 在学习vue源码之前需要先了解源码目录设计(了解各个模块的功能)丶Flow语法. src ├── compiler # 把模板解析成 ast 语法树,ast 语法树优化,代码生成等功能. ├── ...

  4. 【vuejs深入三】vue源码解析之二 htmlParse解析器的实现

    写在前面 一个好的架构需要经过血与火的历练,一个好的工程师需要经过无数项目的摧残. 昨天博主分析了一下在vue中,最为基础核心的api,parse函数,它的作用是将vue的模板字符串转换成ast,从而 ...

  5. [Vue源码分析] 模板的编译

    最近小组有个关于vue源码分析的分享会,提前准备一下- 前言: Vue有两个版本:Runtime + Compiler . Runtime only ,前者是包含编译代码的版本,后者不包含编译代码,编 ...

  6. [Vue源码分析] v-model实现原理

    最近小组有个关于vue源码分析的分享会,提前准备一下- 前言: 我们都知道使用v-model可以实现数据的双向绑定,及实现数据的变化驱动dom的更新,dom的更新影响数据的变化.那么v-model是怎 ...

  7. iris流程图_GitHub - LeoIris/vue: vue源码逐行注释分析+40多m的vue源码程序流程图思维导图 (diff部分待后续更新)...

    vue源码业余时间差不多看了一年,以前在网上找帖子,发现很多帖子很零散,都是一部分一部分说,断章的很多,所以自己下定决定一行行看,经过自己坚持与努力,现在基本看完了 .这个vue源码逐行分析,我基本每 ...

  8. 源码解读_入口开始解读Vue源码系列(二)——new Vue 的故事

    作者:muwoo 转发链接:https://github.com/muwoo/blogs/blob/master/src/Vue/2.md 目录 入口开始解读Vue源码系列(一)--造物创世 入口开始 ...

  9. Vue源码解析:虚拟dom比较原理

    通过对 Vue2.0 源码阅读,想写一写自己的理解,能力有限故从尤大佬2016.4.11第一次提交开始读,准备陆续写: 模版字符串转AST语法树 AST语法树转render函数 Vue双向绑定原理 V ...

  10. Vue源码流程图(函数名与源码对应)

    这里写目录标题 概览 1. 变化侦查 1.1 Observer流程图 2. vdom虚拟DOM 2.1 创建节点createElm 2.2 更新节点patchVnode 2.3 更新子节点 updat ...

最新文章

  1. 如何用 Python 将 Excel 表格转成可视化图形?| 原力计划
  2. 点对点信道互连以太网实验_汽车以太网 – 引领汽车IVN向多速以太网过渡
  3. python读取excel表格-python读取excel表格中的数据
  4. c语言ffffff错误,C语言打印16进制出现0xffffff现象的问题剖析!
  5. ubuntu14.04使用rails连接mysql数据库
  6. tcp http https
  7. MongoDB入门及 c# .netcore客户端MongoDB.Driver2.9.1使用
  8. 14条Yahoo(雅虎)十四条优化原则【转】
  9. android 进程间通信数据(一)------parcel的起源
  10. 浅谈MVC MVP MVVM
  11. python中不论类的名字是什么歌_Python自动猜歌名,还愁排名上不去嘛?
  12. wps居中对齐不在中间_WPS文字快捷键总结(Windows版本)--值得收藏
  13. java 继承对象 初始化_java中具有继承关系的类及其对象初始化顺序
  14. Android模拟器下安装APP报INSTALL_FAILED_NO_MATCHING_ABIS错误解决方案
  15. Pascal VOC Dataset 下载地址
  16. Learning to Rank基于pairwise的算法(三)—— RankNet、FRank、LambdaRank
  17. Archlinux 的灵魂──PKGBUILD、AUR 和 ABS
  18. 关于Gstreamer出现“Could not send sticky events”的机制探究
  19. 计算机修改人类记忆曲线,艾宾浩斯遗忘曲线和费曼技巧
  20. 疫情下的网络舆情管控方案

热门文章

  1. md是什么类型的文件?怎么打开md文件,Markdown的编写,Markdown转化为html
  2. 10.2.1 关于vc++不支持把类的成员函数定义为类的友元函数的处理
  3. 参考文献找不全页码?
  4. Python 基础语法(一)
  5. 程序员的编程艺术第一章
  6. mysql中的merge into,SQL Server 2008中利用merge into关键实现insert/update自动匹配(类似于MySQL中的For Update关键字)...
  7. 生产者跟消费者问题(C++实现)
  8. 将DataFrame中的每一列分别做归一化处理的函数实现
  9. python进制转化大全
  10. Windows系统MySQL安装配置