浅谈vue中.vue文件解析流程


Posted in Javascript onApril 24, 2018

我们平时写的 .vue 文件称为 SFC(Single File Components),本文介绍将 SFC 解析为 descriptor 这一过程在 vue 中是如何执行的。

vue 提供了一个 compiler.parseComponent(file, [options]) 方法,来将 .vue 文件解析成一个 descriptor:

// an object format describing a single-file component.
declare type SFCDescriptor = {
  template: ?SFCBlock;
  script: ?SFCBlock;
  styles: Array<SFCBlock>;
  customBlocks: Array<SFCBlock>;
};

文件入口

解析 sfc 文件的入口在 src/sfc/parser.js 中,该文件 export 了 parseComponent 方法, parseComponent 方法用来对单文件组件进行编译。

接下来我们看看 parseComponent 方法都做了哪些事情。

parseComponent 方法

function start(tag, attrs, unary, start, end,){
}

function end(tag, start, end){
}

parseHTML(content, {
  start,
  end
})

parseComponent 方法中定义了 start``end 两个函数,之后调用了 parseHTML 方法来对 .vue 文件内容践行编译。

那么这个 parseHTML 方法是做啥的呢?

parseHTML 方法

该方法看名字就知道是一个 html-parser,可以简单理解为,解析到每个起始标签时,调用 option 中的 start;每个标签结束时,调用 option 中的 end。

对应到这里,就是分别调用 parseComponent 方法中定义的 start 和 end 函数。

在 parseComponent 中维护一个 depth 变量,在 start 中将 depth++ ,在 end 中 depth-- 。那么,每个 depth === 0 的标签就是我们需要获取的信息,包含 template、script、style 以及一些自定义标签。

start

每当遇到一个起始标签时,执行 start 函数。

1、记录下 currentBlock。

每个 currentBlock 包含以下内容:

declare type SFCBlock = {
  type: string;
  content: string;
  start?: number;
  end?: number;
  lang?: string;
  src?: string;
  scoped?: boolean;
  module?: string | boolean;
};

2、根据 tag 名称,将 currentBlock 对象在返回结果对象中。

返回结果对象定义为 sfc,如果tag不是 script,style,template 中的任一个,就放在 sfc.customBlocks 中。如果是style,就放在 sfc.styles 中。script 和 template 则直接放在 sfc 下。

if (isSpecialTag(tag)) {
  checkAttrs(currentBlock, attrs)
  if (tag === 'style') {
    sfc.styles.push(currentBlock)
  } else {
    sfc[tag] = currentBlock
  }
} else { // custom blocks
  sfc.customBlocks.push(currentBlock)
}

end

每当遇到一个结束标签时,执行 end 函数。

1、如果当前是第一层标签(depth === 1),并且 currentBlock 变量存在,那么取出这部分text,放在 currentBlock.content 中。

if (depth === 1 && currentBlock) {
 currentBlock.end = start
 let text = deindent(content.slice(currentBlock.start, currentBlock.end))
 // pad content so that linters and pre-processors can output correct
 // line numbers in errors and warnings
 if (currentBlock.type !== 'template' && options.pad) {
  text = padContent(currentBlock, options.pad) + text
 }
 currentBlock.content = text
 currentBlock = null
}

2、depth-- 。

得到 descriptor

在将 .vue 整个遍历一遍后,得到的 sfc 对象即为我们需要的结果。

生成 .js ?

compiler.parseComponent(file, [options]) 得到的只是一个组件的 SFCDescriptor ,最终编译成.js 文件是交给 vue-loader 等库来做的。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
基于JQuery的密码强度验证代码
Mar 01 Javascript
25个非常棒的jQuery滑块插件和教程小结
Sep 02 Javascript
javascript设置连续两次点击按钮时间间隔的方法
Oct 28 Javascript
node.js中的fs.chownSync方法使用说明
Dec 16 Javascript
javascript函数特点实例分析
May 14 Javascript
深入理解JS正则表达式---分组
Jul 18 Javascript
AngularJS删除路由中的#符号的方法
Sep 20 Javascript
javascript兼容性(实例讲解)
Aug 15 Javascript
深入理解vue-router之keep-alive
Aug 31 Javascript
实例分析Array.from(arr)与[...arr]到底有何不同
Apr 09 Javascript
layui 动态设置checbox 选中状态的例子
Sep 02 Javascript
JS实现瀑布流效果
Mar 07 Javascript
vue-cli2.9.3 详细教程
Apr 23 #Javascript
vue.js数据绑定操作详解
Apr 23 #Javascript
jQuery+ajax实现动态添加表格tr td功能示例
Apr 23 #jQuery
再谈Angular4 脏值检测(性能优化)
Apr 23 #Javascript
微信小程序之swiper轮播图中的图片自适应高度的方法
Apr 23 #Javascript
vue.js中实现登录控制的方法示例
Apr 23 #Javascript
JS中获取 DOM 元素的绝对位置实例详解
Apr 23 #Javascript
You might like
php 分库分表hash算法
2009/11/12 PHP
PHP实现生成唯一编号(36进制的不重复编号)
2014/07/01 PHP
Laravel中使用自己编写类库的3种方法
2015/02/10 PHP
ThinkPHP 模板substr的截取字符串函数详解
2017/01/09 PHP
input按钮的事件处理大全
2010/12/10 Javascript
jQuery+AJAX实现网页无刷新上传
2015/02/22 Javascript
jQuery中$.ajax()和$.getJson()同步处理详解
2015/08/12 Javascript
Jquery日历插件制作简单日历
2015/10/28 Javascript
js流动式效果显示当前系统时间
2016/05/16 Javascript
Node.js+Express配置入门教程详解
2016/05/19 Javascript
借助node实战JSONP跨域实例
2017/03/30 Javascript
bootstrap基本配置_动力节点Java学院整理
2017/07/14 Javascript
如何选择适合你的JavaScript框架
2017/11/20 Javascript
浅谈webpack打包过程中因为图片的路径导致的问题
2018/02/21 Javascript
Angular4学习笔记router的简单使用
2018/03/30 Javascript
简单的三步vuex入门
2018/05/20 Javascript
详解如何在vue-cli中使用vuex
2018/08/07 Javascript
vue 根据数组中某一项的值进行排序的方法
2018/08/30 Javascript
jQuery+ThinkPHP实现图片上传
2020/07/23 jQuery
使用Vue实现一个树组件的示例
2020/11/06 Javascript
[54:10]Spirit vs NB Supermajor小组赛 A组败者组决赛 BO3 第一场 6.2
2018/06/03 DOTA
Python科学计算之NumPy入门教程
2017/01/15 Python
python模块smtplib实现纯文本邮件发送功能
2018/05/22 Python
Python将文本去空格并保存到txt文件中的实例
2018/07/24 Python
Python基于opencv实现的简单画板功能示例
2019/03/04 Python
使用pyshp包进行shapefile文件修改的例子
2019/12/06 Python
HTML5实现视频直播功能思路详解
2017/11/16 HTML / CSS
使用html5制作loading图的示例
2014/04/14 HTML / CSS
澳大利亚领先的宠物用品商店:VetSupply
2017/09/08 全球购物
Hibernate持久层技术
2013/12/16 面试题
后勤副校长自我鉴定
2013/10/13 职场文书
超市督导岗位职责
2015/04/10 职场文书
2015中秋节晚会主持词
2015/07/01 职场文书
新西兰:最新留学学习计划书写作指南
2019/07/15 职场文书
python 实现图与图之间的间距调整subplots_adjust
2021/05/21 Python
Python 中的Sympy详细使用
2021/08/07 Python