返回
Vue响应式原理学习(三)— Watcher的实现
前端
2024-01-26 07:23:12
众所周知,Vue是在触发数据的get时,收集依赖,改变数据时触发set,达到派发更新的目的。依赖收集和派发更新的代码在上一篇文章,有简单解释过。我们再来重温下代码:
```js
//依赖收集
const target = get(obj, key)
if (target && typeof target === 'object') {
activeEffect(target)
}
//派发更新
if (computed && typeof computed === 'function') {
const context = this._computedWatchers[name]
activeEffect(context)
const res = computed.call(context, this)
activeEffect(dep)
return res
}
这里我省略了部分用于判断和兼容的代码,因为感觉一下子要看所有代码的话,会有些懵比。我们现在知道了,Vue是如何实现响应式的了,那么,下面我们就来看看,Watcher是如何实现的。
Watcher的实现原理其实很简单,就是通过一个类来封装对数据的收集和更新。我们先来看一下Watcher的构造函数:
```js
class Watcher {
constructor(vm, exprOrFn, options, cb) {
this.vm = vm
this.getter = exprOrFn
this.cb = cb
this.options = options
this.dirty = this.lazy // 是否是惰性Watcher
this.deps = [] // 用来存放Watcher依赖的Dep实例
this.newDeps = [] // 用来存放新生成的Dep实例
this.depIds = new Set() // 用来存放Watcher依赖的Dep实例的id
this.newDepIds = new Set() // 用来存放新生成的Dep实例的id
this.getValue() // 初始化时就将依赖收集起来
}
}
可以看到,Watcher的构造函数接收了四个参数:
* vm:当前的Vue实例
* exprOrFn:要监听的数据表达式或函数
* options:一些配置选项,比如lazy、immediate等
* cb:回调函数,在数据变化时触发
Watcher的实现原理很简单,就是通过一个类来封装对数据的收集和更新。我们先来看一下Watcher的构造函数:
```js
class Watcher {
constructor(vm, exprOrFn, options, cb) {
this.vm = vm
this.getter = exprOrFn
this.cb = cb
this.options = options
this.dirty = this.lazy // 是否是惰性Watcher
this.deps = [] // 用来存放Watcher依赖的Dep实例
this.newDeps = [] // 用来存放新生成的Dep实例
this.depIds = new Set() // 用来存放Watcher依赖的Dep实例的id
this.newDepIds = new Set() // 用来存放新生成的Dep实例的id
this.getValue() // 初始化时就将依赖收集起来
}
}
可以看到,Watcher的构造函数接收了四个参数:
* vm:当前的Vue实例
* exprOrFn:要监听的数据表达式或函数
* options:一些配置选项,比如lazy、immediate等
* cb:回调函数,在数据变化时触发
Watcher的实现原理很简单,就是通过一个类来封装对数据的收集和更新。我们先来看一下Watcher的构造函数:
```js
class Watcher {
constructor(vm, exprOrFn, options, cb) {
this.vm = vm
this.getter = exprOrFn
this.cb = cb
this.options = options
this.dirty = this.lazy // 是否是惰性Watcher
this.deps = [] // 用来存放Watcher依赖的Dep实例
this.newDeps = [] // 用来存放新生成的Dep实例
this.depIds = new Set() // 用来存放Watcher依赖的Dep实例的id
this.newDepIds = new Set() // 用来存放新生成的Dep实例的id
this.getValue() // 初始化时就将依赖收集起来
}
}