《Vue 编程房内考》
古人有云:码农爱coding,则为之计深远。
众人问:何为之?
古人曰:底层、算法和架构。
众木然。
古人又曰:多看源码。
以下内容是我在学习 Vue-2.5.2 源码时的一个总结。
第一章 活捉Vue
旁白:既然是学习Vue源码,首先要搞清楚的是——Vue是什么东西?不然,天知道你在学什么玩意儿。所以,找到Vue对象就是本次学习的一条主线。本次任务的目标就是——活捉Vue。
盖工欲善其事必先利其器。出发之前,应该要有一件趁手的武器,呐,这套祖传的vs code就送给你了。
第一回 不入虎穴焉得虎子
欲活捉Vue,最紧要的是找到它大概在哪里,然后根据线索顺藤摸瓜。那么,它到底在哪儿呢?
看着眼前的武器,你灵光一闪:git clone https://github.com/vuejs/vue.git。恭喜,Vue的老巢已经被你发现,令人激动的是,入口package.json也被你找到了。但紧闭的大门阻碍了你的步伐,于是你运用所学姿势,很快找到破解开关的关键scripts属性:
"scripts": {
"dev": "rollup -w -c build/config.js --environment TARGET:web-full-dev",
...
"build": "node build/build.js",
...
}
P.S.package.json几乎是所有成熟库/框架必备的入口文件。
你命令终端执行npm run dev,看到rollup构建工具正在自动执行build文件夹下的config.js,并在环境中注入参数TARGET:web-full-dev,你紧跟线索,找到了build/config.js。看着两百多行代码,你微微一笑,心想,这等雕虫小技也敢造次?径直走向exports,看它导出了什么?
P.S.s 一般而言,导出对象在文件末尾。
// build/config.js
...
if (process.env.TARGET) {
module.exports = genConfig(process.env.TARGET); // (1)
} else {
exports.getBuild = genConfig
exports.getAllBuilds = () => Object.keys(builds).map(genConfig)
}
脑回路高速运行——因为执行npm run dev会植入环境变量TARGET:web-full-dev,上述代码会走(1),所以结合上下文,build/config.js实际导出的对象应该是这样的:
module.exports = {
input: resolve('web/entry-runtime-with-compiler.js'),
plugins: [
replace({__VERSION__: version}),
{
vue: resolve('src/platforms/web/entry-runtime-with-compiler'),
compiler: resolve('src/compiler'),
core: resolve('src/core'),
shared: resolve('src/shared'),
web: resolve('src/platforms/web'),
weex: resolve('src/platforms/weex'),
server: resolve('src/server'),
entries: resolve('src/entries'),
sfc: resolve('src/sfc'),
he: './entity-decoder'
}
],
output: {
file: resolve('dist/vue.js'),
format: 'umd',
banner: banner,
name: 'Vue'
}
}
直到这里,Vue的庐山真面目依然没有揭开。“果然是狡兔三窟!”你不屑道,然而你明白,已经越来越接近了...
此地唯一的入口就是input,小小的障眼法对你来讲不足挂齿,轻轻旋转机关,来到了src/platforms/web/entry-runtime-with-compiler.js。只一眼,你便看到了import Vue from './runtime/index'。"hehe,总算把你逮住了,老东西!"
你小心翼翼的进入./runtime/index,以为终于抓到了Vue。突然,一支利箭飞来import Vue from 'core/index',险险的避过后,一群彪形大汉又蜂拥而至:
./runtime/index.js
import Vue from 'core/index'
...
Vue.config.mustUseProp = mustUseProp
...
extend(Vue.options.directives, platformDirectives)
...
Vue.prototype.$mount = function (
el?: string | Element,
hydrating?: boolean
): Component {
el = el && inBrowser ? query(el) : undefined
return mountComponent(this, el, hydrating)
}
...
第二回 降服Vue
面对群魔乱舞,你开始受伤、流血,一波又一波的攻势逐渐让你体力不支,更糟糕的是,你,只是一个人。“就这样结束了么?”你喘着粗气暗问自己,恍惚间,往昔在脑海中一幕幕重现,从一无所知的小白到现在敢于挑战Vue,经历了重重历练,你不甘心,不甘心就这样失败。放手一搏吧,骚年!!!
体内的能量在积累,终于,你用尽全力使出了终极必杀技:404 Page Not Found。一时间,大汉们应声而倒,就连./runtime/index也开始坍塌,电光火石间,一股大力将你震晕击飞,醒来之时,已经到了另一个世界:src/core/index.js。
这里就是Vue的核心了么?环顾四周,只见一间虚掩着房门的小屋./instance/index,推开门,Vue端坐在那里:
...
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)
}
...
终于找到了,此刻,你可以轻松的把它杀死,成为万众瞩目的英雄,于是乎你挥起手中利刃,直直的刺向Vue。当刃尖离Vue只有0.0001公分的时候,你看着眼前的Vue,原来,鼎鼎大名的Vue只是一个普普通通的构造函数,好像看到了最初的自己,刹那间,你顿住了。
Vue却开口到:“骚年,你终于来了!看你风流倜傥、天资聪颖,老夫这一身绝学总算是后继有人了。”说罢,万丈金光从Vue身上迸发而出,场面一度失控。待金光散去,Vue却不见了,只留下一本《Vue 编程房内考》...
《Vue 编程房内考》的更多相关文章
- 简单物联网:外网访问内网路由器下树莓派Flask服务器
最近做一个小东西,大概过程就是想在教室,宿舍控制实验室的一些设备. 已经在树莓上搭了一个轻量的flask服务器,在实验室的路由器下,任何设备都是可以访问的:但是有一些限制条件,比如我想在宿舍控制我种花 ...
- 利用ssh反向代理以及autossh实现从外网连接内网服务器
前言 最近遇到这样一个问题,我在实验室架设了一台服务器,给师弟或者小伙伴练习Linux用,然后平时在实验室这边直接连接是没有问题的,都是内网嘛.但是回到宿舍问题出来了,使用校园网的童鞋还是能连接上,使 ...
- 外网访问内网Docker容器
外网访问内网Docker容器 本地安装了Docker容器,只能在局域网内访问,怎样从外网也能访问本地Docker容器? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Docker容器 ...
- 外网访问内网SpringBoot
外网访问内网SpringBoot 本地安装了SpringBoot,只能在局域网内访问,怎样从外网也能访问本地SpringBoot? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装Java 1 ...
- 外网访问内网Elasticsearch WEB
外网访问内网Elasticsearch WEB 本地安装了Elasticsearch,只能在局域网内访问其WEB,怎样从外网也能访问本地Elasticsearch? 本文将介绍具体的实现步骤. 1. ...
- 怎样从外网访问内网Rails
外网访问内网Rails 本地安装了Rails,只能在局域网内访问,怎样从外网也能访问本地Rails? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Rails 默认安装的Rails端口 ...
- 怎样从外网访问内网Memcached数据库
外网访问内网Memcached数据库 本地安装了Memcached数据库,只能在局域网内访问,怎样从外网也能访问本地Memcached数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装 ...
- 怎样从外网访问内网CouchDB数据库
外网访问内网CouchDB数据库 本地安装了CouchDB数据库,只能在局域网内访问,怎样从外网也能访问本地CouchDB数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Cou ...
- 怎样从外网访问内网DB2数据库
外网访问内网DB2数据库 本地安装了DB2数据库,只能在局域网内访问,怎样从外网也能访问本地DB2数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动DB2数据库 默认安装的DB2 ...
- 怎样从外网访问内网OpenLDAP数据库
外网访问内网OpenLDAP数据库 本地安装了OpenLDAP数据库,只能在局域网内访问,怎样从外网也能访问本地OpenLDAP数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动 ...
随机推荐
- OpenSCManager
添加服务程序 执行级别:必须管理员
- IPEndPoint
.NET框架用IPEndPoint 对象来表示一个特定的IP地址和端口的组合,应用该对象的场景多是在讲socket绑定到本地地址或者将socket绑定到非本地地址.
- 【转】ORACLE 表空间扩展方法
转载地址:http://blog.itpub.net/28950170/viewspace-763139/ 第一步:查看表空间的名字及文件所在位置: select tablespace_name, f ...
- SPI通信协议(SPI总线)学习
1.什么是SPI? SPI是串行外设接口(Serial Peripheral Interface)的缩写.是 Motorola 公司推出的一 种同步串行接口技术,是一种高速的,全双工,同步的通信总线. ...
- hdu 2153 仙人球的残影
题目 这道题可以有两种写法: 第一种:找规律,如下: #include <stdio.h> int main() { int n,i,j,res; while (scanf("% ...
- mySQl数据库中不能插入中文的处理办法
1. 修改MySQL安装目录下(C:\Program Files\MySQL\MySQL Server 5.5)的my.ini文件 设置: default-character-set=utf8 cha ...
- delphi字符串固定长度换行
var str,capstr:string; i,j:integer; .................... j:=500; //这个地方可能要根据你显示的宽度来换算对应的字符长度 ...
- 自适应XAML布局经验总结 (三) 局部布局设计模式2
本系列对实际项目中的XAML布局场景进行总结,给出了较优化的自适应布局解决方案,希望对大家有所帮助. 下面继续介绍局部布局设计模式. 5. 工具箱模式 绘图,三维模型操作等需要工具的情况,可以使用带分 ...
- 在Azure DevOps Server (TFS) 中修改团队项目名称
概述 [团队项目]: 在Azure DevOps Server (原名TFS)中,团队项目(Team Project)是一个最基本的数据组织容器,包含了一个团队或者信息系统中的所有信息,包括源代码.文 ...
- 手动处理TFS数据仓库服务和分析服务
当您需要报告中最新的数据时,当发生错误时,或者在解决了模式冲突之后,您可以手动处理Team Foundation Server(TFS)关系数据库(TFSHStor)或SQLServer Analys ...