Vue2源码的学习日记(1)

Vue2.js源码分析

作为一个小白学到现在开始对框架有了兴趣,做了一些项目后便想学习一下作者的思想和原理,在这里做一个长久的记录来复习巩固知识,如果哪里有问题,希望各位大佬指出,一定立马修改学习!谢谢!!!

学前准备模块

(在文章中的一切源码大部分都是只给出头部,因为源码是开源的(Vue2.6),我认为在自己去边查找边看的过程也能提升到自己)

Flow

Flow 是 facebook 出品的 JavaScript 静态类型检查工具。Vue.js 的源码就是利用了flow做了静态类型检查。

项目越复杂就要通过工具的手段来保证项目的维护性和增强代码的可读性。vue2则是在ES2015的基础上除了用ESLint保证代码风格还引入了Flow做静态类型检查,而在Babel和ESLint上都有对应的支持Flow的支持语法,所以可以以小成本的改动拥有静态类型检查的能力。

Flow工作方式
  • 类型推断:通过变量的使用上下文来推断出变量类型,然后根据推断来检查类型。
  • 类型注释:事先注释好我们期待的类型,flow会基于这些注释来判断。
Vue.js源码目录
  • compiler:将template编译成render函数,当在线编译时,render运行时执行,并会生成vnode。
  • core:核心代码。
  • platforms: 对于不同平台的支持,如web平台、weex多平台、mpvue小程序端。
  • server:服务端渲染。
  • sfc:单文件处理,.vue文件解析,将vue文件的template、script、style拆分。
  • shared:共享代码,工具、常量等。
compiler

compiler 目录包含 Vue.js 所有编译相关的代码。它包括把模板解析成 ast 语法树,ast 语法树优化,代码生成等功能。编译的工作可以在构建时做(借助 webpack、vue-loader 等辅助插件);也可以在运行时做,使用包含构建功能的 Vue.js。但是编译相对而言会消耗资源,所以离线编译好是个更好的选择。

core

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

platform

Vue.js 是一个跨平台的 MVVM 框架,它可以跑在 web 上,也可以配合 weex 跑在 natvie 客户端上。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.js源码是基于Rollup构建的,它的相关配置都在scripts目录里。在scripts/build.js中,先从配置文件读配置,然后通过命令行参数对构建配置做过滤,来狗i暗处不同用处的Vue.js。

Runtime Only 和Runtime+Compiler

当我们用vue-cli初始化我们的Vue.js项目时会询问我们用哪一种方式,其中各有各的好处

Runtime Only

我们在使用 Runtime Only 版本的 Vue.js 的时候,通常需要借助如 webpack 的 vue-loader 工具把 .vue 文件编译成 JavaScript,因为是在编译阶段做的,所以它只包含运行时的 Vue.js 代码,因此代码体积也会更轻量。

Runtime+Compiler

我们如果没有对代码做预编译,但又使用了 Vue 的 template 属性并传入一个字符串,则需要在客户端编译模板,例:

//需要编译器
new Vue({
    template: '<div>{{ hi }}</div>'
})

//不需要编译器
new Vue({
    render(h) {
        return h('div', this.hi)
    }
})

在Vue.js2.0中,最后的渲染都是通过render函数来进行的,如果有template属性,则要编译成render函数,而这个编译过程对于性能是有损耗的所以一般推荐使用Runtime-Only的Vue.js

从Runtime+compiler的入口开始深入

Runtime+compiler的入口是src/platforms/web/entry-runtime-with-compiler.js

当我们的代码执行 import Vue from 'vue' 的时候,就是从这个入口执行代码来初始化 Vue,这里就不放源码了,但是通过看源码以及分析我们可以看出来Vue实际就是一个用Function实现的类,我们只能通过new Vue来实现。

而Vue.js 在整个初始化过程中,除了给它的原型 prototype 上扩展方法,还会给 Vue 这个对象本身扩展全局的静态方法,它的定义在 src/core/global-api/index.js

export function initGlobalAPI (Vue: GlobalAPI) {...}

现在已经有了一个大致的理解和模糊的概念:Vue本质上就是一个用 Function 实现的 Class,然后它的原型 prototype 以及它本身都扩展了一系列的方法和属性。

  • 7
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

neMew

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值