Vue toys.
一个不能再简单的 Vue
核心代码,一个不能再具体的 Vue
源码分析。(此处用了夸张的修辞手法)。代码参考了vue-come-true/vue-come-true-First,在此感谢原作者的整理。
PS: vue-base.html 需要在最新的 Chrome
上运行,因为用到了很多 ES6
的特性,比如:class
, arrow function
等。当然,作为一个前端,我默认你的 Chrome
版本已经是最新了。
- 模板中的每一个变量都是一个
Watcher
, 通过getter
加入到Dep
的subs
数组中 - 数据中的每一个属性都是一个
Dep
,通过setter
获得更新通知,并告知subs
中的watcher
调用update
方法
你可以从 Google Drive 下载流程图。
-
图中的
DocumentFragment
在实际代码中会用Virtual Dom
代替 -
图中的
Compile
在实际代码中会用HTML Parser
做一些更具体的操作。如编译模板成可生成Virtual Dom
的代码, 具体可查看/test/vue-template-compiler
<div id="list" v-test><span>Hello</span></div>
编译成 (使用
vue-template-compiler
) ==>with(this){return _c('div',{directives:[{name:"test",rawName:"v-test"}],attrs:{"id":"list"}},[_c('span',[_v("Hello")])])}
-
图中的
setter
和getter
方法在实际代码中,还需要对Array
中push
,pop
方法进行拦截,还需要对data
进行深度
绑定。 -
数据监听缺陷
- 无法监听通过数组下标更新的数据
- 无法监听数组 length 的变化
Simple Vue Compiler
基于pure-javascript-html-parser的HTML Parser
(你可以在线测试这个模块)。
ASTElement 是从 HTML 转换到可 render 的代码过程中的中间对象。AST
(Abstract Syntax Tree
): 抽象语法树。(我们在写这个编译器的时候,AST 参考Hypertext Abstract Syntax Tree format )
基本的过程是:模板
=> HTML 模板解析器
=> 抽象语法树
=> 生成可Render的代码
。
在线测试 Simple Vue Compiler ,降模板编译成可Render代码的简易实现。
Vue 中对应的代码
生成可 render
代码后,便可以通过render函数创建 virtual dom
了。
console.log(1);
Promise.resolve().then(() => console.log(2))
setTimeout(() => console.log(3), 0);
setTimeout(() => console.log(4), 0);
Promise.resolve().then(() => console.log(5))
console.log(6);
/*
output:
1 6 2 5 3 4
*/
更多关于 Promise
, Mutation observers
, Microtasks
的,请查看 Tasks, microtasks, queues and schedules.