入口开始,解读Vue源码(一)-- 造物创世
Why?
网上现有的Vue源码解析文章一搜一大批,但是为什么我还要去做这样的事情呢?因为觉得纸上得来终觉浅,绝知此事要躬行。
然后平时的项目也主要是Vue,在使用Vue的过程中,也对其一些约定产生了一些疑问,可能官网上只会建议你这么做,但是核心实现我们可能并不知道。比如:
- v-for key 是如何达到“就地复用”策略
- 数组更新检测是如何完成的
- set 为什么就能动态添加根级别的响应式属性
- 为什么Vue可以跨平台支持weex,以及后来出现的mpvue
- ...
其次,很久没有更新内容了,之前对Vue源码也是有点研究,只不过没有很体系的记录,现在抽了点时间,做了一次基础的总结吧。一方面是因为想要克服自己的惰性,另一方面也是想重新温故一遍。
What?
一共分成了10个基础部分,后续还会继续记录。我们可以先看一下概览:
然后我们来看一下基础的目录:
入口开始,解读Vue源码(三)—— initMixin 上篇
入口开始,解读Vue源码(三)—— initMixin 下篇
入口开始,解读Vue源码(四)—— 实现一个基础的 Vue 双向绑定
入口开始,解读Vue源码(六)—— $mount 内部实现 --- compile parse函数生成AST
入口开始,解读Vue源码(七)—— $mount 内部实现 --- compile optimize标记节点
入口开始,解读Vue源码(八)—— $mount 内部实现 --- compile generate 生成render函数
入口开始,解读Vue源码(九)—— $mount 内部实现 --- render函数 --> VNode
入口开始,解读Vue源码(十)—— $mount 内部实现 --- patch
开篇:入口开始,解读Vue源码(一)-- 造物创世
世间万物的起源来自于盘古的开天辟地,Vue 项目的起源,源于一次Vue的实例化:
new Vue({
el: ...,
data: ...,
....
})
那么在这次实例化的过程中,究竟发生了哪些行为?让我们来一探究竟。打开Vue的源码文件,其核心代码在src/core目录下。下面我们从入口文件index.js开始进入:(刚开始看的时候,我们可能不太清楚每个引用方法的具体实现,不过没关系,我们可以自己根据他的命名来YY一下。)
// src/core/index.js
// 这里应该是我们 Vue 核心方法
import Vue from './instance/index'
// 根据命名,应该可以猜出这里是初始化一些全局API
import { initGlobalAPI } from './global-api/index'
// 根据命名,这里应该是获取一个Boolean类型的变量,来判断是不是ssr
import { isServerRendering } from 'core/util/env'
// 这里开始执行初始化全局变量
initGlobalAPI(Vue)
// 为Vue原型定义属性$isServer
Object.defineProperty(Vue.prototype, '$isServer', {
get: isServerRendering
})
// 为Vue原型定义属性$ssrContext
Object.defineProperty(Vue.prototype, '$ssrContext', {
get () {
/* istanbul ignore next */
return this.$vnode && this.$vnode.ssrContext
}
})
Vue.version = '__VERSION__'
export default Vue
下面我们来一步步验证我们的猜测,首先找到core/instance/index文件,可以清晰的看到:
import { initMixin } from './init'
import { stateMixin } from './state'
import { renderMixin } from './render'
import { eventsMixin } from './events'
import { lifecycleMixin } from './lifecycle'
import { warn } from '../util/index'
function Vue (options) {
if (process.env.NODE_ENV !== 'production' &&
!(this instanceof Vue)
) {
warn('Vue is a constructor and should be called with the `new` keyword')
}
this._init(options)
}
initMixin(Vue)
stateMixin(Vue)
eventsMixin(Vue)
lifecycleMixin(Vue)
renderMixin(Vue)
export default Vue
这里简单粗暴的定义了一个 Vue Class,然后又调用了一系列init、mixin这样的方法来初始化一些功能,具体的我们后面在分析,不过通过代码我们可以确认的是:没错!这里确实是导出了一个 Vue 功能类。
接下来,我们接着看initGlobalAPI这个东西,其实在Vue官网上,就已经为我们说明了Vue的全局属性:

那我们来看看,是不是这么回事(内容太多,只贴一下主要的代码):
// core/global-api/index
...
export function initGlobalAPI (Vue: GlobalAPI) {
// config
const configDef = {}
configDef.get = () => config
if (process.env.NODE_ENV !== 'production') {
configDef.set = () => {
warn(
'Do not replace the Vue.config object, set individual fields instead.'
)
}
}
Object.defineProperty(Vue, 'config', configDef)
// 这些工具方法不视作全局API的一部分,除非你已经意识到某些风险,否则不要去依赖他们
Vue.util = {
warn,
extend,
mergeOptions,
defineReactive
}
// 这里定义全局属性
Vue.set = set
Vue.delete = del
Vue.nextTick = nextTick
Vue.options = Object.create(null)
ASSET_TYPES.forEach(type => {
Vue.options[type + 's'] = Object.create(null)
})
Vue.options._base = Vue
extend(Vue.options.components, builtInComponents)
// 定义全局方法
initUse(Vue)
initMixin(Vue)
initExtend(Vue)
initAssetRegisters(Vue)
}
【Vue.config】 各种全局配置项
【Vue.util】 各种工具函数,还有一些兼容性的标志位(哇,不用自己判断浏览器了,Vue已经判断好了)
【Vue.set/delete】 这个你文档应该见过
【Vue.nextTick】
【Vue.options】 这个options和我们上面用来构造实例的options不一样。这个是Vue默认提供的资源(组件指令过滤器)。
【Vue.use】 通过initUse方法定义
【Vue.mixin】 通过initMixin方法定义
【Vue.extend】通过initExtend方法定义
接下来便是提供给ssr使用的全局变量$isServer 和 $ssrContext。 关于他们的使用,其实ssr文档也有说明:Head 管理
到这里,我们的入口文件差不多就了解清楚了,接下来,我们开始去了解一下 Vue class 的具体实现,其中我们会了解到Vue的相关生命周期的知识。
End?
文章前后也是利用碎片时间总结整理而成,有些也是翻阅了很多的资料,也有过引用巨人的段落,文章中有所标注。如果没有标注,可能是本人忘记了,欢迎提醒。文章中如果有笔误或者不正确的解释,也欢迎批评指正,共同进步。
最后:
入口开始,解读Vue源码(一)-- 造物创世的更多相关文章
- 入口文件开始,分析Vue源码实现
Why? 网上现有的Vue源码解析文章一搜一大批,但是为什么我还要去做这样的事情呢?因为觉得纸上得来终觉浅,绝知此事要躬行. 然后平时的项目也主要是Vue,在使用Vue的过程中,也对其一些约定产生了一 ...
- VUE源码解析心得
解读vue源码比较好奇的几个点: VUE MVVM 原理 http://www.cnblogs.com/guwei4037/p/5591183.html https://cn.vuejs.org/v2 ...
- Vue 源码解读(1)—— 前言
当学习成为了习惯,知识也就变成了常识. 感谢各位的 点赞.收藏和评论. 新视频和文章会第一时间在微信公众号发送,欢迎关注:李永宁lyn 文章已收录到 github 仓库 liyongning/blog ...
- Vue 源码解读(2)—— Vue 初始化过程
当学习成为了习惯,知识也就变成了常识. 感谢各位的 点赞.收藏和评论. 新视频和文章会第一时间在微信公众号发送,欢迎关注:李永宁lyn 文章已收录到 github 仓库 liyongning/blog ...
- Vue 源码解读(3)—— 响应式原理
前言 上一篇文章 Vue 源码解读(2)-- Vue 初始化过程 详细讲解了 Vue 的初始化过程,明白了 new Vue(options) 都做了什么,其中关于 数据响应式 的实现用一句话简单的带过 ...
- Vue 源码解读(5)—— 全局 API
目标 深入理解以下全局 API 的实现原理. Vue.use Vue.mixin Vue.component Vue.filter Vue.directive Vue.extend Vue.set V ...
- Vue 源码解读(6)—— 实例方法
前言 上一篇文章 Vue 源码解读(5)-- 全局 API 详细介绍了 Vue 的各个全局 API 的实现原理,本篇文章将会详细介绍各个实例方法的实现原理. 目标 深入理解以下实例方法的实现原理. v ...
- Vue 源码解读(8)—— 编译器 之 解析(上)
特殊说明 由于文章篇幅限制,所以将 Vue 源码解读(8)-- 编译器 之 解析 拆成了上下两篇,所以在阅读本篇文章时请同时打开 Vue 源码解读(8)-- 编译器 之 解析(下)一起阅读. 前言 V ...
- Vue 源码解读(9)—— 编译器 之 优化
前言 上一篇文章 Vue 源码解读(8)-- 编译器 之 解析 详细详解了编译器的第一部分,如何将 html 模版字符串编译成 AST.今天带来编译器的第二部分,优化 AST,也是大家常说的静态标记. ...
随机推荐
- Python之旅.第二章数据类型 3.19/3.20/3.21/3.22/3.23
一.数字类型 1.int类型: 基本使用: 用途:用于年龄,手机号,身份证号: 定义: age=18: 常用操作+内置方法: 正常的运算赋值: 进制转换: print(bin(3)); 把十进制3转换 ...
- python入门(14)定义函数和接收返回值
定义函数: 定义一个求绝对值的my_abs函数为例: def my_abs(x): if x >= 0: return x else: return -x 如果没有return语句,函数执行完毕 ...
- RxJava系列3(转换操作符)
RxJava系列1(简介) RxJava系列2(基本概念及使用介绍) RxJava系列3(转换操作符) RxJava系列4(过滤操作符) RxJava系列5(组合操作符) RxJava系列6(从微观角 ...
- 两款不同应用场景的Wpf分页控件
简介 今天给大家分享两个Wpf分页控件,本篇博客主要介绍一些实现思路和使用方法,具体实现和应用代码请参考文末的Demo链接 废话不多说,先看一下效果~ (两款控件显示效果是一样的) 实现思路 一款控件 ...
- pthon/零起点(一、集合)
pthon/零起点(一.集合) set( )集合,集合是无序的,集合是可变的,集合是可迭代的 set()强型转成集合数据类型 set()集合本身就是去掉重复的元素 集合更新操作案列: j={1,2,3 ...
- Python scrapy框架
Scrapy Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架. 其可以应用在数据挖掘,信息处理或存储历史数据等一系列的程序中.其最初是为了页面抓取 (更确切来说, 网络抓取 )所设 ...
- 网络配置及shell基础
一:集群已做完 二:临时配置网络(ip,网关,dns)+永久配置 临时配置网络: ip: [root@localhost ~]# ifconfig [root@localhost ~]# ifc ...
- spring boot 系列之二:spring boot 如何修改默认端口号和contextpath
上一篇文件我们通过一个实例进行了spring boot 入门,我们发现tomcat端口号和上下文(context path)都是默认的, 如果我们对于这两个值有特殊需要的话,需要自己制定的时候怎么办呢 ...
- html超文本标记语言的由来
万维网上的一个超媒体文档称为一个页面:page,作为一个组织或者个人在万维网上放置开始点的页面称为主页:homepage或者首页,主页中通常有指向其他相关页面或者其他节点的指针,就是通常所说的超链接, ...
- requests-post请求
post与get方法的区别在于post需要提交一些数据以备处理. 在requests里面非常简单,headers,data都是直接加进去就可以了 # requests.post提交表单# 有些网站使用 ...