说明
- Vue 版本:2.5.13
正文
先来看看 Vue 的配置,以组件为例
{
render(h) {
},
props: {
props1: Number
},
data() {
return {
data1: 1,
data2: 0
}
},
computed: {
computed1() {
return this.data1 + this.props1
}
},
watch: {
computed1(newValue) {
setTimeout(()=>{
console.log(newValue)
},0)
}
}
}
响应式实现过程大概可以分为三块:
数据 Data
初始化 data、props、computed 时(初始化 render 时还有一些其他内置属性),通过 Object.defineProperty
将属性定义成 get
和 set
,并为每个属性绑定一个 Dep 实例。
详见 src/core/instance/state.js
中 initData
和 initProps
。
组件 Component
可以把整个 Vue 应用认为是大大小小的组件堆砌而成。Vue 为每个组件都定义了两块重要的内容:Watcher 和 Render。
执行 $mount
时调用 mountComponent
、初始化 watch、computed时、调用实例方法 $watch时,都会给实例化一个 Watcher。而 Watcher 初始化时会进行一次求值(执行实例中的 getter
方法),首先会将当前实例设置为 Dep 当前目标,然后触发数据的相关属性的 get
方法。
详见 src/core/instance/state.js
中 initComputed
和 initWatch
。
依赖 Dep
Dep
类就是用来关联数据与组件的 Watcher 的。
// the current target watcher being evaluated.
// this is globally unique because there could be only one
// watcher being evaluated at any time.
Dep.target = null
其实初始化 Watcher 时,通过执行了对应属性的 get
方法,将Watcher 实例放入数据对应的 Dep 实例的订阅列表中。而当数据发生变化时,对应属性执行 set
方法,会通知到对应的 Dep 实例,再通知订阅列表中的 Watcher。
此时,Watcher 将通知组件执行 Render,重新计算出新的 VNode,通过新旧 VNode 的对比,进行视图更新。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。