.6-Vue源码之AST(2)
上一节获取到了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', ' ') : 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)相关推荐
- 什么是php的ast结构,什么是AST?Vue源码中AST语法树的解析
这篇文章给大家介绍的内容是关于什么是AST?Vue源码中AST语法树的解析,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 什么是AST AST是指抽象语法树(abstract syn ...
- Vue源码解析之Template转化为AST的实现方法
什么是AST 在Vue的mount过程中,template会被编译成AST语法树,AST是指抽象语法树(abstract syntax tree或者缩写为AST),或者语法树(syntax tree) ...
- vue实例没有挂载到html上,vue 源码学习 - 实例挂载
前言 在学习vue源码之前需要先了解源码目录设计(了解各个模块的功能)丶Flow语法. src ├── compiler # 把模板解析成 ast 语法树,ast 语法树优化,代码生成等功能. ├── ...
- 【vuejs深入三】vue源码解析之二 htmlParse解析器的实现
写在前面 一个好的架构需要经过血与火的历练,一个好的工程师需要经过无数项目的摧残. 昨天博主分析了一下在vue中,最为基础核心的api,parse函数,它的作用是将vue的模板字符串转换成ast,从而 ...
- [Vue源码分析] 模板的编译
最近小组有个关于vue源码分析的分享会,提前准备一下- 前言: Vue有两个版本:Runtime + Compiler . Runtime only ,前者是包含编译代码的版本,后者不包含编译代码,编 ...
- [Vue源码分析] v-model实现原理
最近小组有个关于vue源码分析的分享会,提前准备一下- 前言: 我们都知道使用v-model可以实现数据的双向绑定,及实现数据的变化驱动dom的更新,dom的更新影响数据的变化.那么v-model是怎 ...
- iris流程图_GitHub - LeoIris/vue: vue源码逐行注释分析+40多m的vue源码程序流程图思维导图 (diff部分待后续更新)...
vue源码业余时间差不多看了一年,以前在网上找帖子,发现很多帖子很零散,都是一部分一部分说,断章的很多,所以自己下定决定一行行看,经过自己坚持与努力,现在基本看完了 .这个vue源码逐行分析,我基本每 ...
- 源码解读_入口开始解读Vue源码系列(二)——new Vue 的故事
作者:muwoo 转发链接:https://github.com/muwoo/blogs/blob/master/src/Vue/2.md 目录 入口开始解读Vue源码系列(一)--造物创世 入口开始 ...
- Vue源码解析:虚拟dom比较原理
通过对 Vue2.0 源码阅读,想写一写自己的理解,能力有限故从尤大佬2016.4.11第一次提交开始读,准备陆续写: 模版字符串转AST语法树 AST语法树转render函数 Vue双向绑定原理 V ...
- Vue源码流程图(函数名与源码对应)
这里写目录标题 概览 1. 变化侦查 1.1 Observer流程图 2. vdom虚拟DOM 2.1 创建节点createElm 2.2 更新节点patchVnode 2.3 更新子节点 updat ...
最新文章
- 如何用 Python 将 Excel 表格转成可视化图形?| 原力计划
- 点对点信道互连以太网实验_汽车以太网 – 引领汽车IVN向多速以太网过渡
- python读取excel表格-python读取excel表格中的数据
- c语言ffffff错误,C语言打印16进制出现0xffffff现象的问题剖析!
- ubuntu14.04使用rails连接mysql数据库
- tcp http https
- MongoDB入门及 c# .netcore客户端MongoDB.Driver2.9.1使用
- 14条Yahoo(雅虎)十四条优化原则【转】
- android 进程间通信数据(一)------parcel的起源
- 浅谈MVC MVP MVVM
- python中不论类的名字是什么歌_Python自动猜歌名,还愁排名上不去嘛?
- wps居中对齐不在中间_WPS文字快捷键总结(Windows版本)--值得收藏
- java 继承对象 初始化_java中具有继承关系的类及其对象初始化顺序
- Android模拟器下安装APP报INSTALL_FAILED_NO_MATCHING_ABIS错误解决方案
- Pascal VOC Dataset 下载地址
- Learning to Rank基于pairwise的算法(三)—— RankNet、FRank、LambdaRank
- Archlinux 的灵魂──PKGBUILD、AUR 和 ABS
- 关于Gstreamer出现“Could not send sticky events”的机制探究
- 计算机修改人类记忆曲线,艾宾浩斯遗忘曲线和费曼技巧
- 疫情下的网络舆情管控方案
热门文章
- md是什么类型的文件?怎么打开md文件,Markdown的编写,Markdown转化为html
- 10.2.1 关于vc++不支持把类的成员函数定义为类的友元函数的处理
- 参考文献找不全页码?
- Python 基础语法(一)
- 程序员的编程艺术第一章
- mysql中的merge into,SQL Server 2008中利用merge into关键实现insert/update自动匹配(类似于MySQL中的For Update关键字)...
- 生产者跟消费者问题(C++实现)
- 将DataFrame中的每一列分别做归一化处理的函数实现
- python进制转化大全
- Windows系统MySQL安装配置