浅谈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 相关文章推荐
JS对外部文件的加载及对IFRMAME的加载的实现,当加载完成后,指定指向方法(方法回调)
Jul 04 Javascript
点击button获取text内容并改变样式的js实现
Sep 09 Javascript
js窗口关闭提示信息(兼容IE和firefox)
Oct 23 Javascript
js实现div在页面拖动效果
May 04 Javascript
jQuery图片瀑布流的简单实现代码
Mar 15 Javascript
用最简单的方法判断JavaScript中this的指向(推荐)
Sep 04 Javascript
vue中v-model动态生成的实例详解
Oct 27 Javascript
vue-prop父组件向子组件进行传值的方法
Mar 01 Javascript
vue 解决addRoutes多次添加路由重复的操作
Aug 04 Javascript
封装Vue Element的table表格组件的示例详解
Aug 19 Javascript
vue点击按钮实现简单页面的切换
Sep 08 Javascript
PHP 502bad gateway原因及解决方案
Nov 13 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设计模式  Command(命令模式)
2011/06/17 PHP
ThinkPHP文件上传实例教程
2014/08/22 PHP
jquery 插件学习(六)
2012/08/06 Javascript
基于JavaScript实现 获取鼠标点击位置坐标的方法
2013/04/12 Javascript
jQuery实现表头固定效果的实例代码
2013/05/24 Javascript
解析Node.js基于模块和包的代码部署方式
2016/02/16 Javascript
基于AngularJS+HTML+Groovy实现登录功能
2016/02/17 Javascript
通过node-mysql搭建Windows+Node.js+MySQL环境的教程
2016/03/01 Javascript
手机移动端实现 jquery和HTML5 Canvas的幸运大奖盘特效
2016/12/06 Javascript
js正则表达式验证密码强度【推荐】
2017/03/03 Javascript
jQuery实现注册会员时密码强度提示信息功能示例
2017/09/05 jQuery
JavaScript数据结构之双向链表和双向循环链表的实现
2017/11/28 Javascript
Vue实现自定义下拉菜单功能
2018/07/16 Javascript
Vue中jsx不完全应用指南小结
2019/11/01 Javascript
JS实现transform实现扇子效果
2020/01/17 Javascript
python应用程序在windows下不出现cmd窗口的办法
2014/05/29 Python
浅谈Python中的可变对象和不可变对象
2017/07/07 Python
django中的setting最佳配置小结
2017/11/21 Python
Python KMeans聚类问题分析
2018/02/23 Python
Python基于socket模块实现UDP通信功能示例
2018/04/10 Python
python 将列表中的字符串连接成一个长路径的方法
2018/10/23 Python
用Python实现筛选文件脚本的方法
2018/10/27 Python
django配置连接数据库及原生sql语句的使用方法
2019/03/03 Python
很酷的python表白工具 你喜欢我吗
2019/04/11 Python
python logging 日志的级别调整方式
2020/02/21 Python
用 Python 制作地球仪的方法
2020/04/24 Python
深入分析python 排序
2020/08/24 Python
HTML5 embed 标签使用方法介绍
2013/08/13 HTML / CSS
煤矿班组长岗位职责
2013/12/29 职场文书
企业党员公开承诺书
2014/03/26 职场文书
今冬明春火灾防控工作方案
2014/05/29 职场文书
助人为乐模范事迹材料
2014/06/02 职场文书
中国在我心中演讲稿
2014/09/13 职场文书
大学生求职信怎么写
2015/03/19 职场文书
《迟到》教学反思
2016/02/24 职场文书
idea编译器vue缩进报错问题场景分析
2021/07/04 Vue.js