Vue 初始化
先从最简单的一段 Vue 代码开始:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <template> <div> {{ message }} </div> </template> <script> new Vue({ data() { return { message: "hello world", }; }, }); </script>
|
这段代码很简单,最终会在页面上打印一个 hello world,它是如何实现的呢?
我们从源头:new Vue 的地方开始分析。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
|
function walk(obj) { const keys = Object.keys(obj); for (let i = 0; i < keys.length; i++) { defineReactive(obj, keys[i]); } }
function defineReactive(obj, key, val) { const dep = new Dep(); Object.defineProperty(obj, key, { get() { const value = val; if (Dep.target) { dep.depend(); } return value; }, set(newVal) { val = newVal; dep.notify(); }, }); }
|
…
总结
从 new Vue 开始,首先通过 get、set 监听 Data 中的数据变化,同时创建 Dep 用来搜集使用该 Data 的 Watcher。
编译模板,创建 Watcher,并将 Dep.target 标识为当前 Watcher。
编译模板时,如果使用到了 Data 中的数据,就会触发 Data 的 get 方法,然后调用 Dep.addSub 将 Watcher 搜集起来。
数据更新时,会触发 Data 的 set 方法,然后调用 Dep.notify 通知所有使用到该 Data 的 Watcher 去更新 DOM。