PENGINE
算法
数据库
前端
后端
工具
vue3源码分析:响应式原理
2026-08-07 16:40:25

模仿vue3 实现最简单的响应式系统

入口文件:index.js

import {reactive} from "./reactive.js"
import {effect} from "./effect.js"
const state = reactive({
    count: 1,
})
//对应源码中componentUpdateFn函数,简化方法体,响应式数据被访问时,可触发 依赖收集 即可
const componentUpdateFn = ()=>{
    console.log("count:", state.count)
}
effect(componentUpdateFn)
state.count = 3

reactive.js

import {track, trigger} from "./dep.js"

const reactiveMap = new WeakMap();//存储 原始对象=>响应式代理对象 映射关系

export function reactive(target) {
    //将要代理的数据必须是对象
    if(typeof target !== 'object'|| target === null) {
        return target
    }

    const existingTarget = reactiveMap.get(target)
    if(existingTarget) {
        return existingTarget
    }
    const proxy = new Proxy(target, {
        get(target, key,receiver) {
            const result = Reflect.get(target, key,receiver)
            // 收集依赖
            console.log('收集依赖')
            track(target, key)
            return result;
        },
        set(target, key, value,receiver) {
            const oldValue = target[key];
            const result = Reflect.set(target, key, value,receiver);
            if(oldValue !== value) {
            // 通知更新
            console.log('通知更新')
            trigger(target, key);
            }
            return result;
        },
    })
    reactiveMap.set(target, proxy)
    return proxy;
}


effect.js

export let activeEffect = undefined
export class ReactiveEffect {
    fn;
    deps = [];
    constructor(fn) {
        this.fn = fn;
    }

    run(){
        activeEffect = this;
        const result = this.fn();
        activeEffect = undefined;
        return result;
    }
}

export function effect(fn){
    const reactiveEffect = new ReactiveEffect(fn);
    const update = reactiveEffect.run.bind(reactiveEffect);
    update();
}

dep.js

import {activeEffect,} from "./effect.js"

const targetMap = new WeakMap()

export class Dep {
    subscribers = new Set()
    track(){
        if(!activeEffect){
            return
        }
        // 已经存在不重复添加
        if(!this.subscribers.has(activeEffect)){
            this.subscribers.add(
                activeEffect
            )
            // 反向记录
            activeEffect.deps.push(
                this
            )
        }
    }

    trigger(){
        this.subscribers.forEach(
            effect=>{
                    effect.run()
            }
        )
    }
}


// 收集依赖
export function track(target, key){
    if(!activeEffect){
        return
    }
    let depsMap =targetMap.get(target)
    if(!depsMap){
        depsMap = new Map()
        targetMap.set(
            target,
            depsMap
        )
    }
    let dep = depsMap.get(key)
    if(!dep){
        dep =new Dep()
        depsMap.set(key, dep)
    }
    dep.track()
}

//通知更新
export function trigger(target, key){
    const depsMap =targetMap.get(target)
    if(!depsMap){
        return
    }
    const dep =depsMap.get(key)
    if(dep){
        dep.trigger()
    }
}


测试:

node index.js

结果:

收集依赖
count: 1
通知更新
收集依赖
count: 3
辽ICP备15018437号-3