Vue 2 模版编译流程详解

网站建设3年前发布
66 0 0

Vue 2 模版编译流程详解图片,vue 中有这样一张响应式系统的流程图,vue 会将模板语法编译成 render 函数,通过 render 函数渲染生成 Virtual dom,但是官方并没有对模板编译有详细的介绍,这篇文章带大家一起学习下 vue 的模板编译。,为了更好理解 vue 的模板编译这里我整理了一份模板编译的整体流程,如下所示,下面将用源码解读的方式来找到模板编译中的几个核心步骤,进行详细说明:,Vue 2 模版编译流程详解图片,这里我使用 webpack 来打包 vue 文件,来分析 vue 在模板编译中的具体流程,如下所示,下面是搭建的项目结构和文件内容:,如上 webpack.config.js 所示,webpack 可以通过 vue-loader 识别 vue 文件,vue-loader 是 webpack 用来解析 .vue 文件的 loader,主要作用是将单文件组件(SFC),解析成为 webpack 可识别的 JavaScript 模块。,搭建好整个目录项目后,执行 npm run build ,会将 vue 文件解析打包成对应的 bundle,并输出至 dist 目录下,下面是打包后的产出,对应 App.vue 的产物:,从上方的产物可以看出,App.vue 文件被编译分为三块,_App_vue_vue_type_template_id_7ba5bd90_scoped_true___WEBPACK_IMPORTED_MODULE_0__  _App_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_1___node_modules_vue_loader_lib_runtime_componentNormalizer_js__WEBPACK_IMPORTED_MODULE_2__,这三个模块恰好对应vue模板中的 templatescriptstyle这三个标签的模板内容,所以得出结论:vue-loader 会将 vue 模板中的templatescriptstyle 标签内容分解为三个模块。为此,我找到 vue-loader 的源码,下面分析其源码逻辑:,源码里很清楚的可以看到 vue-loader 使用了 vue/compiler-sfc 中的 parse 方法对 vue 的源文件进行的解析,将模板语法解析为一段可描述的对象,对 descriptor 进行打印,输出结果如下,vue-loader 对源文件编译后,vue 模板会被转化成抽象语法树(AST),此处便是模板编译的入口,使用编译后的 AST 将 vue 模板拆分为 template 、script 和 style 三部分,方便后面 webpack 通过 resourceQuery 匹配分发到各个loader 进行二次解析编译,template 部分会被 template-loader 进行二次编译解析,最终生成render 函数。,template-loader 的作用是将 import { render, staticRenderFns } from "./App.vue?vue&type=template&id=7ba5bd90&" 模块编译成 render 函数并导出,以下是编译产物:,template-loader 核心原理是通过 vue/compiler-sfc 将模板转换成为 render 函数,并返回 template 编译产物,vue/compiler-sfc 是模板编译的核心库,在 vue2.7 版本中使用,而 vue2.7 以下的版本都是使用vue-template-compiler,本质两个包的功能是一样的,都可以将模板语法编译为 JavaScript,接下来我们来解析一下在模板编译过程中使用的方法:,可以将 vue 文件中的模板语法转义为 AST,为后续创建 dom 结构做预处理,genElement 会将 AST 预发转义为字符串代码,后续可将其包装成 render 函数的返回值,通过genElement函数包装处理后,将vue 模板的 template 标签部分转换为 render 函数,如下所示:,将 genElement 阶段编译的字符串产物,通过 new Function将 code 转为函数,为了方便理解,使用断点调试,来看一下 compileTemplate 都经历了哪些操作:,首先会判断是否需要预处理,如果需要预处理,则会对 template 模板进行预处理并返回处理结果,此处跳过预处理,直接进入 actuallCompile 函数,这里可以看到本身内部还有一层编译函数对 template 进行编译,这才是最核心的编译方法,而这个 compile 方法来源于 createCompilerCreator,Vue 2 模版编译流程详解图片,createCompilerCreator 返回了两层函数,最终返回值则是 compile 和 compileToFunction,这两个是将 template 转为 render 函数的关键,可以看到 template 会被解析成 AST 树,最后通过 generate 方法转义成函数 code,接下来我们看一下parse函数中是如何将 template 转为 AST 的。,Vue 2 模版编译流程详解图片,继续向下 debug 后,会走到 parseHTML 函数,这个函数是模板编译中用来解析 HTML 结构的核心方法,通过回调 + 递归最终遍历整个 HTML 结构并将其转化为 AST 树。,使用 parseHTML 解析成的 AST 创建 render 函数和 Vdom,Vue 2 模版编译流程详解图片,将 AST 结构解析成为虚拟 dom 树,Vue 2 模版编译流程详解图片,最终编译输出为 render 函数,得到最终打包构建的产物。,Vue 2 模版编译流程详解图片,到此我们应该了解了 vue 是如何打包构建将模板编译为渲染函数的,有了渲染函数后,只需要将渲染函数的 this 指向组件实例,即可和组件的响应式数据绑定。vue 的每一个组件都会对应一个渲染 Watcher ,他的本质作用是把响应式数据作为依赖收集,当响应式数据发生变化时,会触发 setter 执行响应式依赖通知渲染 Watcher 重新执行 render 函数做到页面数据的更新。,vue 2 官方文档 ( https://v2.cn.vuejs.org/ )

© 版权声明

相关文章