浅谈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 相关文章推荐
精通Javascript系列之Javascript基础篇
Jun 07 Javascript
浅析JavaScript中的CSS属性及命名规范
Nov 28 Javascript
javascript与css3动画结合使用小结
Mar 11 Javascript
JavaScript中var关键字的使用详解
Aug 14 Javascript
AngularJS中的包含详细介绍及实现示例
Jul 28 Javascript
AngularJS入门教程之表单校验用法示例
Nov 02 Javascript
详解JavaScript时间处理之几个月前或几个月后的指定日期
Dec 21 Javascript
关于iframe跨域POST提交的方法示例
Jan 15 Javascript
HTML5+Canvas调用手机拍照功能实现图片上传(下)
Apr 21 Javascript
vue弹窗组件使用方法
Apr 28 Javascript
vue.js的vue-cli脚手架中使用百度地图API的实例
Jan 21 Javascript
原生js实现日期选择插件
May 21 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 接口类与抽象类的实际作用
2009/11/26 PHP
PHP array_multisort()函数的使用札记
2011/07/03 PHP
关于ob_get_contents(),ob_end_clean(),ob_start(),的具体用法详解
2013/06/24 PHP
使用Appcan客户端自动更新PHP版本号(全)
2015/07/31 PHP
PHP中new static()与new self()的比较
2016/08/19 PHP
PHP进制转换实例分析(2,8,16,36,64进制至10进制相互转换)
2017/02/04 PHP
JavaScript中的History历史对象
2008/01/16 Javascript
JS 文件传参及处理技巧分析
2010/05/13 Javascript
jquery异步跨域访问代码
2013/06/28 Javascript
indexOf 和 lastIndexOf 使用示例介绍
2014/09/02 Javascript
JavaScript setTimeout使用闭包功能实现定时打印数值
2015/12/18 Javascript
深入理解vue-loader如何使用
2017/06/06 Javascript
JS跳转手机站url的若干注意事项
2017/10/18 Javascript
详解react-redux插件入门
2018/04/19 Javascript
vue中音频wavesurfer.js的使用方法
2020/02/20 Vue.js
JavaScript交换变量的常用方法小结【4种方法】
2020/05/07 Javascript
JavaScript实现多层颜色选项卡嵌套
2020/09/21 Javascript
基于vue的video播放器的实现示例
2021/02/19 Vue.js
[04:22]DOTA2上海特级锦标赛主赛事第四日TOP10
2016/03/06 DOTA
github配置使用指南
2014/11/18 Python
Python利用turtle库绘制彩虹代码示例
2017/12/20 Python
Python遍历文件夹 处理json文件的方法
2019/01/22 Python
Python学习笔记之抓取某只基金历史净值数据实战案例
2019/06/03 Python
把django中admin后台界面的英文修改为中文显示的方法
2019/07/26 Python
python3 selenium自动化 下拉框定位的例子
2019/08/23 Python
python输入一个水仙花数(三位数) 输出百位十位个位实例
2020/05/03 Python
如何在Anaconda中打开python自带idle
2020/09/21 Python
AmazeUI 加载进度条的实现示例
2020/08/20 HTML / CSS
美国户外生活方式品牌:Eddie Bauer
2016/12/28 全球购物
租房协议书
2014/04/10 职场文书
公司爱心捐款倡议书
2014/05/14 职场文书
干部竞争上岗演讲稿
2014/09/11 职场文书
个人整改措施落实情况汇报
2014/10/29 职场文书
欢迎词怎么写
2015/01/23 职场文书
中学教师个人总结
2015/02/10 职场文书
2015年统战工作总结
2015/05/19 职场文书