浅谈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某一元素重复绑定的问题
Jan 03 Javascript
jquery ztree实现模糊搜索功能
Feb 25 Javascript
JavaScript中的this陷阱的最全收集并整理(没有之一)
Feb 21 Javascript
基于 webpack2 实现的多入口项目脚手架详解
Jun 26 Javascript
自定义vue组件发布到npm的方法
May 09 Javascript
基于vue实现可搜索下拉框定制组件
Mar 26 Javascript
详解nuxt 微信公众号支付遇到的问题与解决
Aug 26 Javascript
解决LayUI数据表格复选框不居中显示的问题
Sep 25 Javascript
express中static中间件的具体使用方法
Oct 17 Javascript
微信小程序 SOTER 生物认证DEMO 指纹识别功能
Dec 13 Javascript
ES5和ES6中类的区别总结
Dec 21 Javascript
用React Native制作一个简单的游戏引擎
May 27 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 内存缓存加速功能memcached安装与用法
2009/09/03 PHP
php使用fsockopen函数发送post,get请求获取网页内容的方法
2014/11/15 PHP
双冒号 ::在PHP中的使用情况
2015/11/05 PHP
JS+CSS实现一个气泡提示框
2013/08/18 Javascript
基于jquery的文字向上跑动类似跑马灯的效果
2014/09/22 Javascript
JS实现带提示的星级评分效果完整实例
2015/10/30 Javascript
ECMA5数组的新增方法有哪些及forEach()模仿实现
2015/11/03 Javascript
Angular2 环境配置详细介绍
2016/09/21 Javascript
有关文件上传 非ajax提交 得到后台数据问题
2016/10/12 Javascript
JavaScript &amp; jQuery完美判断图片是否加载完毕
2017/01/08 Javascript
解决canvas画布使用fillRect()时高度出现双倍效果的问题
2017/08/03 Javascript
JS非空验证及邮箱验证的实例
2017/08/11 Javascript
nodejs超出最大的调用栈错误问题
2017/12/27 NodeJs
微信小程序自定义对话框弹出和隐藏动画
2018/07/19 Javascript
vue生命周期和react生命周期对比【推荐】
2018/09/19 Javascript
JavaScript创建防篡改对象的方法分析
2018/12/30 Javascript
highCharts提示框中显示当前时间的方法
2019/01/18 Javascript
Vue 2.0 中依赖注入 provide/inject组合实战
2019/06/20 Javascript
Vue+Koa2+mongoose写一个像素绘板的实现方法
2019/09/10 Javascript
JS Web Flex弹性盒子模型代码实例
2020/03/10 Javascript
vue3.0生命周期的示例代码
2020/09/24 Javascript
python re模块findall()函数实例解析
2018/01/19 Python
Python paramiko 模块浅谈与SSH主要功能模拟解析
2020/02/29 Python
Python tempfile模块生成临时文件和临时目录
2020/09/30 Python
在python中对于bool布尔值的取反操作
2020/12/11 Python
pytorch中index_select()的用法详解
2021/01/06 Python
Draper James官网:知名演员瑞茜·威瑟斯彭所创品牌
2017/10/25 全球购物
Puma印度官网:德国运动品牌
2019/10/06 全球购物
澳大利亚在线购买葡萄酒:The Wine Collective
2020/02/20 全球购物
高中生班主任评语
2014/04/25 职场文书
在教室放鞭炮的检讨书
2014/09/28 职场文书
学校政风行风整改方案
2014/10/25 职场文书
公司酒会主持词
2015/07/02 职场文书
外出培训学习心得体会
2016/01/18 职场文书
详解RedisTemplate下Redis分布式锁引发的系列问题
2021/04/27 Redis
Pandas-DataFrame知识点汇总
2022/03/16 Python