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 = newVal
        trigger(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 = effect
        return fn()
    }
    effect.deps = []
    return effect
}
// trigger
function trigger(target, key) {
    const depMap = targetMap.get(target)
    if (!depMap) return
    const 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链接

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值