浅谈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 事件属性绑定带参数的函数
Mar 13 Javascript
利用js读取动态网站从服务器端返回的数据
Feb 10 Javascript
模拟用户点击弹出新页面不会被浏览器拦截
Apr 08 Javascript
jQuery中阻止冒泡事件的方法介绍
Apr 12 Javascript
在JavaScript中使用timer示例
May 08 Javascript
javascript包装对象实例分析
Mar 27 Javascript
jquery插件orbit.js实现图片折叠轮换特效
Apr 14 Javascript
jQuery超酷平面式时钟效果代码分享
Mar 30 Javascript
Paypal支付不完全指北
Jun 04 Javascript
微信h5静默和非静默授权获取用户openId的方法和步骤
Jun 08 Javascript
在Vue中获取自定义属性方法:data-id的实例
Sep 09 Javascript
Vue实现购物车基本功能
Nov 08 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
调整优化您的LAMP应用程序的5种简单方法
2011/06/26 PHP
解析PHP留言本模块主要功能的函数说明(代码可实现)
2013/06/25 PHP
学习php设计模式 php实现单例模式(singleton)
2015/12/07 PHP
Linux基于php-fpm模式的lamp搭建phpmyadmin的方法
2018/10/25 PHP
PHP实现获取文件mime类型多种方法解析
2020/05/28 PHP
php实现记事本案例
2020/10/20 PHP
JavaScript脚本语言在网页中的简单应用
2007/05/13 Javascript
用JQuery实现表格隔行变色和突出显示当前行的代码
2012/02/10 Javascript
JS注册/移除事件处理程序(ExtJS应用程序设计实战)
2013/05/07 Javascript
详解AngularJS中的表达式使用
2015/06/16 Javascript
日常收集整理的JavaScript常用函数方法
2015/12/10 Javascript
纯JS代码实现一键分享功能
2016/04/20 Javascript
JS作用域深度解析
2016/12/29 Javascript
JS正则匹配URL网址的方法(可匹配www,http开头的一切网址)
2017/01/06 Javascript
Angularjs中ng-repeat的简单实例
2017/08/25 Javascript
详解jQuery中的isPlainObject()使用方法
2018/02/27 jQuery
jQuery子选择器与可见性选择器实例分析
2019/06/28 jQuery
Vue编程式跳转的实例代码详解
2019/07/10 Javascript
JS实现在线ps功能详解
2019/07/31 Javascript
详解利用eventemitter2实现Vue组件通信
2019/11/04 Javascript
微信小程序 wx.getUserInfo引导用户授权问题实例分析
2020/03/09 Javascript
JavaScript随机数的组合问题案例分析
2020/05/16 Javascript
小程序Scroll-view上拉滚动刷新数据
2020/06/21 Javascript
Vue 集成 PDF.js 实现 PDF 预览和添加水印的步骤
2021/01/22 Vue.js
python正则匹配查询港澳通行证办理进度示例分享
2013/12/27 Python
Python判断字符串与大小写转换
2015/06/08 Python
Python工程师面试必备25条知识点
2018/01/17 Python
浅析python表达式4+0.5值的数据类型
2020/02/26 Python
优秀员工年终发言演讲稿
2014/01/01 职场文书
关于爱情的广播稿
2014/01/16 职场文书
红头文件任命书范本
2014/06/05 职场文书
运动会加油口号
2014/06/07 职场文书
幼儿园教师安全责任书
2015/05/08 职场文书
使用canvas实现雪花飘动效果的示例代码
2021/03/30 HTML / CSS
关于Javascript闭包与应用的详解
2021/04/22 Javascript
python机器学习Github已达8.9Kstars模型解释器LIME
2021/11/23 Python