示例代码托管在:http://www.github.com/dashnowords/blogs

博客园地址:《大史住在大前端》原创博文目录

华为云社区地址:【你要的前端打怪升级指南】

一. 简述

compiler模块Vue框架中用于模板编译的,它的作用就是将Vue中的组件模板转换成render函数,render函数在运行时可以生成虚拟节点vnode,它是Vue中虚拟DOM树的基本实现流程。完整版的Vue是包含runtimecompiler的,也就是说模板的编译过程可以在运行时进行,这无疑是一种性能负担。Vue官方也提供了独立的runtime版本,其中只包含运行时环境,把从templaterender函数的生成部分放在构建时完成(利用vue-templete-compiler模块),以提高运行时的效率。

由于跨平台需求,compiler模块的实现过程步骤稍多,不断地利用高阶函数来拆分整体逻辑,不是很容易阅读,本篇对该模块的基本流程进行一个梳理,再参考文末彩蛋推荐的电子书,就比较容易看懂了。

二. 编译流程

相关入口在实例挂载函数$mount的实现中:

Vue.prototype.$mount = function(){
const options = this.$options
//....
const { render, staticRenderFns } = compileToFunctions(template, {
shouldDecodeNewlines,
shouldDecodeNewlinesForHref,
delimiters: options.delimiters,
comments: options.comments
}, this)
options.render = render
options.staticRenderFns = staticRenderFns
//....
return mount.call(this, el, hydrating)
}

可以看到实例挂载方法$mount的逻辑就是在调用mount方法前在实例的$options添加了额外的信息。此处调用的compileToFunctions方法经历的逻辑跳转了多层高阶函数,涉及文件也比较多,直接上图比较清楚:

笔者将涉及函数简化为输入输出的形式:

核心逻辑步骤如下所示:

梳理完流程,整个编译流程的宏观流程也就相对清晰了,这里为了兼顾不同平台的方法差异,将有差异的部分提取为独立的模块,然后作为函数参数注入执行函数,这种通过高阶函数来组织代码的方式能提高核心逻辑的聚合程度,如果是普通的业务逻辑,很可能会是以扁平化串联调用的形式来编写方法的,笔者个人认为两种模式没有绝对的优劣对比,虽然高阶函数看起来更高级。

三. 彩蛋环节

分享一本非常详细的讲述Vue核心原理的开源电子书【Vue.js 技术揭秘】

Vue源码中compiler部分逻辑梳理(内有彩蛋)的更多相关文章

  1. 【Vue】VUE源码中的一些工具函数

    Vue源码-工具方法 /* */ //Object.freeze()阻止修改现有属性的特性和值,并阻止添加新属性. var emptyObject = Object.freeze({}); // th ...

  2. Vue源码翻译之渲染逻辑链

    本篇文章主要要记录说明的是,Vue在Vdom的创建上的相关细节.这也是描绘了Vue在界面的创建上的一个逻辑顺序,同时我也非常拜服作者编码的逻辑性,当然或许这么庞大复杂的编码不是一次性铸就的,我想应该也 ...

  3. vue源码中computed和watch的解读

    computed 会基于其内部的 响应式依赖 进行缓存. 只在相关 响应式依赖发生改变 时 它们才会重新求值. 可以在将模板中使用的常量放在计算属性中. watch 监听数据变化,并在监听回调函数中返 ...

  4. 了解一下vue源码中vue 的由来

     我们之前提到过 Vue.js 构建过程,在 web 应用下,我们来分析 Runtime + Compiler 构建出来的 Vue.js,它的入口是 src/platforms/web/entry-r ...

  5. nodeType属性在vue源码中的使用

    每个节点都有一个 nodeType 属性,用于表明节点的类型,节点类型由 Node 类型中定义12个常量表示:  nodeType在vue中的应用 在vue编译的过程中需要查找html结构中的双大括号 ...

  6. 从Vue源码中我学到了几点精妙方法

    话不多说,赶快试试这几个精妙方法吧!在工作中肯定会用得到. 立即执行函数 页面加载完成后只执行一次的设置函数. (function (a, b) { console.log(a, b); // 1,2 ...

  7. Vue源码解析---数据的双向绑定

    本文主要抽离Vue源码中数据双向绑定的核心代码,解析Vue是如何实现数据的双向绑定 核心思想是ES5的Object.defineProperty()和发布-订阅模式 整体结构 改造Vue实例中的dat ...

  8. 学习Vue源码前的几项必要储备(二)

    7项重要储备 Flow 基本语法 发布/订阅模式 ES6+ 语法 原型链.闭包 函数柯里化 event loop 接上讲 聊到了ES6的几个重要语法,加下来到第四点继续开始. 4.原型链.闭包 原型链 ...

  9. 【Vue源码学习】依赖收集

    前面我们学习了vue的响应式原理,我们知道了vue2底层是通过Object.defineProperty来实现数据响应式的,但是单有这个还不够,我们在data中定义的数据可能没有用于模版渲染,修改这些 ...

随机推荐

  1. 100天搞定机器学习|Day15 朴素贝叶斯

    Day15,开始学习朴素贝叶斯,先了解一下贝爷,以示敬意. 托马斯·贝叶斯 (Thomas Bayes),英国神学家.数学家.数理统计学家和哲学家,1702年出生于英国伦敦,做过神甫:1742年成为英 ...

  2. Linux 常用命令及详解

    1.  type   :查询命令 是否属于shell解释器2.  help  : 帮助命令3.  man : 为所有用户提供在线帮助4.  ls  : 列表显示目录内的文件及目录-l    以长格式显 ...

  3. main方法中注入Spring bean

    在有些情况下需要使用main使用Spring bean,但是main方法启动并没有托管给Spring管理,会导致bean失败,报空指针异常. 可以使用 ClassPathXmlApplicationC ...

  4. Linux启动之旅

    引言 某出租房内,某台电脑的电源键被按下,于是开启了一段Linux启动之旅... BIOS 系统启动,首先进入BIOS. ● BIOS 为 Base Input/Output System(基本输入输 ...

  5. Java——集合类

    1.容器的打印 import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import jav ...

  6. android——Fragment

    谷歌官方文档的介绍: https://developer.android.com/guide/components/fragments.html#Design Fragment 表示 Activity ...

  7. 【0805 | Day 8】Python进阶(二)

    列表类型内置方法 一.列表类型内置方法(list) 用途:多个爱好.多个武器.多种化妆品 定义:[ ]内可以有多个任意类型的值,逗号分隔元素 # my_boy_friend = list(['jaso ...

  8. Appium+python自动化(三十一)- 元芳,你怎么看? - 日志收集-logging(超详解)

    简介 生活中的日志是记录你生活的点点滴滴,让它把你内心的世界表露出来,更好的诠释自己的内心世界,而电脑里的日志是有价值的信息宝库. 日志文件是专门用于记录系统操作事件的记录文件或文件集合,操作系统有操 ...

  9. Spring AOP JDK动态代理与CGLib动态代理区别

    静态代理与动态代理 静态代理 代理模式 (1)代理模式是常用设计模式的一种,我们在软件设计时常用的代理一般是指静态代理,也就是在代码中显式指定的代理. (2)静态代理由 业务实现类.业务代理类 两部分 ...

  10. Python循环语句及函数的定义

      循环语句¶ 重复执行某一个固定的动作或者任务 语法 for 变量 in序列: 语句1 语句2 ..... In [2]: # 列表知识只是以后会讲 # 比如[1,2,3,4,5,6,7] list ...