浅谈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读取ASP设定的COOKIE
Feb 15 Javascript
jquery怎样实现ajax联动框(二)
Mar 08 Javascript
Javascript 颜色渐变效果的实现代码
Oct 01 Javascript
jQuery Validate 验证,校验规则写在控件中的具体实例
Feb 27 Javascript
jquery控制display属性为none或block
Mar 31 Javascript
基于HTML+CSS,jQuery编写的简易计算器后续(添加了键盘监听)
Jan 05 Javascript
基于HTML5+JS实现本地图片裁剪并上传功能
Mar 24 Javascript
jQuery实现鼠标响应式透明度渐变动画效果示例
Feb 13 jQuery
vue 国际化 vue-i18n 双语言 语言包
Jun 07 Javascript
Vue Router的懒加载路径的解决方法
Jun 21 Javascript
JQuery常见节点操作实例分析
May 15 jQuery
React生命周期原理与用法踩坑笔记
Apr 28 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的输入输出流
2007/02/14 PHP
用Zend Encode编写开发PHP程序
2010/02/21 PHP
javascript 火狐(firefox)不显示本地图片问题解决
2008/07/05 Javascript
js判断浏览器类型的方法
2013/08/07 Javascript
js如何判断输入字符串长度
2015/12/16 Javascript
js图片上传前预览功能(兼容所有浏览器)
2016/08/24 Javascript
JQuery和PHP结合实现动态进度条上传显示
2016/11/23 Javascript
详解jQuery中基本的动画方法
2016/12/14 Javascript
jQuery实现优雅的弹窗效果(6)
2017/02/08 Javascript
javascript实现二叉树遍历的代码
2017/06/08 Javascript
利用jquery去掉时光轴头尾部线条的方法实例
2017/06/16 jQuery
vue 本地环境跨域请求proxyTable的方法
2018/09/19 Javascript
浅谈VUE-CLI脚手架热更新太慢的原因和解决方法
2018/09/28 Javascript
JS实现的A*寻路算法详解
2018/12/14 Javascript
json字符串对象转换代码实例
2019/09/28 Javascript
JS highcharts动态柱状图原理及实现
2020/10/16 Javascript
[02:48]DOTA2英雄基础教程 拉席克
2013/12/12 DOTA
如何使用pyinstaller打包32位的exe程序
2019/05/26 Python
python字符串替换re.sub()方法解析
2019/09/18 Python
Python Selenium参数配置方法解析
2020/01/19 Python
python 函数嵌套及多函数共同运行知识点讲解
2020/03/03 Python
tensorflow dataset.shuffle、dataset.batch、dataset.repeat顺序区别详解
2020/06/03 Python
详解Python中第三方库Faker
2020/09/25 Python
澳大利亚免息网上购物:Shop Zero
2016/09/17 全球购物
巴西购物网站:Estrela10
2018/12/13 全球购物
大一期末自我鉴定
2013/12/13 职场文书
信息技术专业大学生职业生涯规划书
2014/01/24 职场文书
带病坚持工作事迹
2014/05/03 职场文书
遵纪守法演讲稿
2014/05/23 职场文书
小学优秀教师事迹材料
2014/12/16 职场文书
综合素质自我评价评语
2015/03/06 职场文书
证券公司客户经理岗位职责
2015/04/09 职场文书
学雷锋团日活动总结
2015/05/06 职场文书
2019年让高校“心动”的自荐信
2019/03/25 职场文书
英文诗歌翻译方法(赏析)
2019/08/16 职场文书
使用python向MongoDB插入时间字段的操作
2021/05/18 Python