vue3 的依赖收集原理

总结来说: vue使用模块全局变量来进行依赖收集

极简版的vue3 依赖收集源码

// 以vue3 ref为例
// 定义响应式对象, 对外接口 ref
function ref(value) {return createRef(value)
}function createRef(value) {return new RefImpl(value)
}class RefImpl {constructor(value) {this._value = value}get value() {track(this, 'value')return this._value}set value(newVal) {this._value = newValtrigger(this, 'value')}
}// 依赖收集部分
const targetMap = new WeakMap()
let activeEffect
function track(target, key) {let depMap = targetMap.get(target)if (!depMap) {targetMap.set(target, (depMap = new Map())) }let deps = depMap.get(key)if (!deps) {depMap.set(key, deps = new Set())}if(activeEffect) {deps.add(activeEffect)activeEffect.deps.push(deps)}
}// 副作用部分
function effect(fn) {const effect1 = createReactiveEffect(fn)effect1()
}function createReactiveEffect(fn) {const effect =  function reactiveEffect() {activeEffect = effectreturn fn()}effect.deps = []return effect
}
// trigger
function trigger(target, key) {const depMap = targetMap.get(target)if (!depMap) returnconst deps = depMap.get(key)deps.forEach(dep => {dep()})
}
  1. 对外暴漏两个api, ref 和effect
  2. ref用于创建一个基本值的包装对象RefImpl的实例
  3. RefImpl的getter中会触发依赖收集
  4. RefImpl的getter中会触发包装对象,也就是值的订阅者
  5. effec会创建一个effect的函数, 并且立即执行一次,把全局变量activeEffect设置为本身, 并在effect中执行订阅函数
  6. 订阅函数会立即触发ref的getter, 从而触发track,把当前的effect加入订阅者列表里
  7. 当ref实例的value改变时, 会触发trigger,从而触发订阅者

github链接


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部