浅谈vue中.vue文件解析流程

所属分类: 网络编程 / JavaScript 阅读数: 841
收藏 0 赞 0 分享

我们平时写的 .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 等库来做的。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

更多精彩内容其他人还在看

BootStrap数据表格实例代码

本文通过实例代码给大家分享了BootStrap数据表格的相关知识,感兴趣的朋友一起看看吧
收藏 0 赞 0 分享

基于vue的短信验证码倒计时demo

这篇文章主要介绍了基于vue的短信验证码倒计时demo,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

详解React Native开源时间日期选择器组件(react-native-datetime)

本篇文章主要介绍了详解React Native开源时间日期选择器组件(react-native-datetime),具有一定的参考价值,有兴趣的可以了解一下
收藏 0 赞 0 分享

JS库particles.js创建超炫背景粒子插件(附源码下载)

particles.js用于创建粒子的轻量级 JavaScript 库。使用方法非常简单,代码也很容易实现,下面通过本文给大家分享JS库particles.js创建超炫背景粒子插件附源码下载,需要的朋友参考下吧
收藏 0 赞 0 分享

JS库之Waypoints的用法详解

waypoints的功能非常强大,一款用于捕获各种滚动事件的插件,下面跟随脚本之家小编一起学习JS库之Waypoints的用法吧
收藏 0 赞 0 分享

强大的JavaScript响应式图表Chartist.js的使用

本篇文章主要介绍了强大的JavaScript响应式图表Chartist.js的使用,具有一定的参考价值,有兴趣的可以了解一下
收藏 0 赞 0 分享

详解wow.js中各种特效对应的类名

本篇文章主要介绍了wow.js中各种特效对应的类名 ,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

JS库之Highlight.js的用法详解

highlight.js是一款轻量级的Web代码语法高亮库。下面通过实例代码给大家分享JS库之Highlight.js的用法详解,感兴趣的朋友跟随脚本之家小编一起学习吧
收藏 0 赞 0 分享

详解动画插件wow.js的使用方法

本篇文章主要介绍了动画插件wow.js的使用方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

JS库 Highlightjs 添加代码行号的实现代码

Highlightjs是一款优秀的代码高亮Js组件,可以很方便地对各种语言编写的代码添加语法高亮样式。本文重点给大家介绍Highlightjs 添加代码行号的实现代码,需要的朋友参考下吧
收藏 0 赞 0 分享
查看更多