Vue源码分析(一) : new Vue() 做了什么

author: @TiffanysBear

在了解new Vue做了什么之前,我们先对Vue源码做一些基础的了解,如果你已经对基础的源码目录设计等有基础的了解的话,可以跳过下面这部分。

源码目录设计

Vue.js 的源码都在 src 目录下,其目录结构如下。

src
├── compiler # 编译相关
├── core # 核心代码
├── platforms # 不同平台的支持
├── server # 服务端渲染
├── sfc # .vue 文件解析
├── shared # 共享代码

compiler

compiler 目录包含 Vue.js 所有编译相关的代码。它包括把模板解析成 AST 语法树,AST语法树优化,代码生成等功能。

编译的工作可以在构建时做(可以借助 webpack、vue-loader 等插件);也可以在运行时做,使用包含构建功能的 Vue.js。编译是一项耗性能的工作,所以更推荐前者——离线编译。

core

core 目录包含了 Vue.js 的核心代码,包括有内置组件、全局 API 封装,Vue 实例化、Obsever、Virtual DOM、工具函数 Util 等等。

platform

Vue.js 是一个跨平台的 MVVM 框架,它可以跑在 web 上,也可以配合 weex 跑在 native 客户端上。platform 是 Vue.js 的入口,2 个目录代表 2 个主要入口,分别打包成运行在 web 上和 weex 上的 Vue.js。

server

Vue.js 2.0 支持了服务端渲染,所有服务端渲染相关的逻辑都在这个目录下。注意:这部分代码是跑在服务端的 Node.js,不要和跑在浏览器端的 Vue.js 混为一谈。

服务端渲染主要的工作是把组件渲染为服务器端的 HTML 字符串,将它们直接发送到浏览器,最后将静态标记"混合"为客户端上完全交互的应用程序。

sfc

通常我们开发 Vue.js 都会借助 webpack 构建, 然后通过 .vue 单文件来编写组件。

这个目录下的代码逻辑会把 .vue 文件内容解析成一个 JavaScript 的对象。

shared

Vue.js 会定义一些工具方法,这里定义的工具方法都是会被浏览器端的 Vue.js 和服务端的 Vue.js 所共享的。

接下来我们来找一下Vue的入口文件,我们接下来的分析都是基于platform为web的环境下进行的分析,从 package.json 和 config的 的打包配置中里可以看出,运行在web环境 (Runtime only (CommonJS))的入口文件在 web/entry-runtime.js下。

Vue入口文件

Vue入口文件目录 vue/src/core/instance/index.js

// vue/src/core/instance/index.js
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

采用的是ES5的写法,并不是ES6的Class写法的优点,是因为:

1、使用混入Mixin的方式传入Vue,为Vue的原型prototype上增加方法。class难以实现这种方法

2、此种方式将代码模块合理划分,将扩展分散到多个模块中去实现,使得代码文件不会过于庞大,便于维护和管理。这个编程技巧以后可以用于代码开发实现中。

通过Mixin增加的原型方法:

// vue/src/core/instance/index.js
initMixin(Vue) // _init
stateMixin(Vue) // $set、$delete、$watch
eventsMixin(Vue) // $on、$once、$off、$emit
lifecycleMixin(Vue) // _update、$forceUpdate、$destroy、
renderMixin(Vue) // $nextTick、_render

initGlobalAPI

在 vue/src/core/index.js 中,调用的initGlobalAPI(Vue),是为Vue增加静态方法的,

在路径 vue/src/core/global-api/ 目录下的文件中,都是给Vue添加的静态方法

比如:

Vue.use // 使用plugin
Vue.extend
Vue.mixin
Vue.component
Vue.directive
Vue.filter

有了这些基础的了解和一步步的跟踪查找后,我们一步一步找到了 new Vue 所在的位置,接下来我们来看下 new Vue 到底做了什么?

new Vue 做了什么

从入口的文件看来,通过new关键字初始化,调用了

// src/core/instance/index.js

this._init(options)

然后从Mixin增加的原型方法看,initMixin(Vue),调用的是为Vue增加的原型方法_init

// src/core/instance/init.js

Vue.prototype._init = function (options?: Object) {
const vm: Component = this
....
....
// expose real self
vm._self = vm
initLifecycle(vm)
initEvents(vm)
initRender(vm)
callHook(vm, 'beforeCreate')
initInjections(vm) // resolve injections before data/props
initState(vm)
initProvide(vm) // resolve provide after data/props
callHook(vm, 'created') ....
.... if (vm.$options.el) {
vm.$mount(vm.$options.el)
}
}

所以,从上面的函数看来,new vue所做的事情,就像一个流程图一样展开了,分别是

  • 合并配置
  • 初始化生命周期
  • 初始化事件中心
  • 初始化渲染
  • 调用 beforeCreate 钩子函数
  • init injections and reactivity(这个阶段属性都已注入绑定,而且被 $watch 变成reactivity,但是 $el 还是没有生成,也就是DOM没有生成)
  • 初始化state状态(初始化了data、props、computed、watcher)
  • 调用created钩子函数。

在初始化的最后,检测到如果有 el 属性,则调用 vm.$mount 方法挂载 vm,挂载的目标就是把模板渲染成最终的 DOM。

Vue代码初始化的主线逻辑非常分明,使得逻辑和流程非常清楚,这种编程方法值得学习。

最后

现在的部分只是粗略的函数上讲了 new Vue 的过程和含义,接下来的文档会继续对Vue的源码进行学习和分析,会接着更细地分析在生命周期lifecyle下每一个函数后面具体所做的事情。

Vue源码分析(一) : new Vue() 做了什么的更多相关文章

  1. vue源码分析之new Vue过程

    实例化构造函数 从这里可以看出new Vue实际上是使vue构造函数实例化,然后调用_init方法 _init方法,该方法在 src/core/instance/init.js 中定义 Vue.pro ...

  2. vue 快速入门 系列 —— 侦测数据的变化 - [vue 源码分析]

    其他章节请看: vue 快速入门 系列 侦测数据的变化 - [vue 源码分析] 本文将 vue 中与数据侦测相关的源码摘了出来,配合上文(侦测数据的变化 - [基本实现]) 一起来分析一下 vue ...

  3. 前端Vue 源码分析-逻辑层

    Vue 源码分析-逻辑层 预期的效果: 监听input的输入,input在输入的时候,会触发 watch与computed函数,并且会更新原始的input的数值.所以直接跟input相关的处理就有3处 ...

  4. Vue源码分析(二) : Vue实例挂载

    Vue源码分析(二) : Vue实例挂载 author: @TiffanysBear 实例挂载主要是 $mount 方法的实现,在 src/platforms/web/entry-runtime-wi ...

  5. [Vue源码分析] v-model实现原理

    最近小组有个关于vue源码分析的分享会,提前准备一下… 前言:我们都知道使用v-model可以实现数据的双向绑定,及实现数据的变化驱动dom的更新,dom的更新影响数据的变化.那么v-model是怎么 ...

  6. [Vue源码]一起来学Vue模板编译原理(一)-Template生成AST

    本文我们一起通过学习Vue模板编译原理(一)-Template生成AST来分析Vue源码.预计接下来会围绕Vue源码来整理一些文章,如下. 一起来学Vue双向绑定原理-数据劫持和发布订阅 一起来学Vu ...

  7. [Vue源码]一起来学Vue模板编译原理(二)-AST生成Render字符串

    本文我们一起通过学习Vue模板编译原理(二)-AST生成Render字符串来分析Vue源码.预计接下来会围绕Vue源码来整理一些文章,如下. 一起来学Vue双向绑定原理-数据劫持和发布订阅 一起来学V ...

  8. [Vue源码]一起来学Vue双向绑定原理-数据劫持和发布订阅

    有一段时间没有更新技术博文了,因为这段时间埋下头来看Vue源码了.本文我们一起通过学习双向绑定原理来分析Vue源码.预计接下来会围绕Vue源码来整理一些文章,如下. 一起来学Vue双向绑定原理-数据劫 ...

  9. vue源码分析—Vue.js 源码目录设计

    Vue.js 的源码都在 src 目录下,其目录结构如下 src ├── compiler # 编译相关 ├── core # 核心代码 ├── platforms # 不同平台的支持 ├── ser ...

随机推荐

  1. iOS 中 UIView 和 CALayer 的关系

    UIView 有一个名叫 layer ,类型为 CALayer 的对象属性,它们的行为很相似,主要区别在于:CALayer 继承自 NSObject ,不能够响应事件. 这是因为 UIView 除了负 ...

  2. AM--消息队列

    kafka rocketMq零拷贝对比 https://cloud.tencent.com/developer/news/333695 还有Linux目录下的基本原理 RocketMQ Kafka C ...

  3. 【年度盘点】10个热门Python练习项目

    这10个项目,约有270000人学习过. 今天给大家盘点一下实验楼最热门的10个Python练习项目.第二名是<200 行 Python 代码实现 2048>,第三名是<Python ...

  4. spice在桌面虚拟化中的应用系列之一(spice简介,性能优化等)

    1.spice介绍 1.1 spice简介 spice是由Qumranet开发的开源网络协议,2008年红帽收购了Qumranet获得了这个协议.SPICE是红帽在虚拟化领域除了KVM的又一“新兴技术 ...

  5. 2019-ACM-ICPC-徐州站网络赛-M.Longest subsequence-从字符串s中找到一个最长子序列,使得其字典序严格大于t

    2019-ACM-ICPC-徐州站网络赛-M.Longest subsequence-从字符串s中找到一个最长子序列,使得其字典序严格大于t [Problem Description] ​ 从字符串\ ...

  6. Windows设置多用户同时远程登录

    1.在键盘上按Win+R键(也可以在开始菜单右键然后选择运行),在运行的输入框里面输入"gpedit.msc"命令.然后点击确定 ​ 2.在“计算机组策略”中依次展开 计算机配置- ...

  7. MySQL进阶19--函数的创建(举例)/设置mysql的创建函数的权限/查看(show)/删除(drop) / 举4个栗子

    /*MySQL进阶19 函数 存储过程和函数:都类似于java中的方法; 存储过程和函数通用好处: 1.提高代码的重用性 2.简化操作 好处: 减少操作次数,减少了编译次数,减少了和服务器的连接次数, ...

  8. P1352 没有上司的舞会[树形dp]

    题目描述 某大学有N个职员,编号为1~N.他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司.现在有个周年庆宴会,宴会每邀请来一个职员都会增加一定的快乐指数Ri, ...

  9. matlab(3) Logistic Regression: 求cost 和gradient \ 求sigmoid的值

    sigmoid.m文件 function g = sigmoid(z)%SIGMOID Compute sigmoid functoon% J = SIGMOID(z) computes the si ...

  10. Composer的安装以及替换为国内镜像

    Composer的安装以及使用国内镜像 Composer 学习网址 Composer官网 https://getcomposer.org/ Composer中文网 http://www.phpcomp ...