vue3相比于vue2有了显著的性能晋升,而最间接的就是从Object.defineProperty换成了proxy做数据劫持,而effect是响应式零碎的外围,响应式零碎又是vue3中的外围。

最根本的响应式就是我扭转一个值,另一个值也主动做出变动。

此时咱们执行一下文件会看到达到了咱们想要的目标。当然这并不是咱们最终想要的,咱们看一下vue3是如何做的。
在vue3中reactivity能够作为一个独自的模块下载。

effect函数执行了两次,在第一次传入匿名函数的时候执行了一次 在之后a变量的值发生变化的时候又执行了一次。

当初咱们本人来实现一个响应式零碎。
响应式最重要的就是收集依赖和触发依赖。
1.创立一个类用来收集和触发依赖

2.在申明变量时触发收集操作

这时候就和vue3中的ref很像了。当初能够优化一下。将在收集依赖时手动调用depend办法改为在get办法中调用,在变量从新赋值时手动调用notice办法改为在set中调用。

3.创立一个reactive函数,return一个Proxy对象

在Proxy中应用get来拦挡取值行为并return出对应后果。这里咱们应用的是ES6新的Reflect函数。相干文档点击这里,总之Reflect.get(target,key)相当于target[key]。

4.创立全局map用于存储所有的对象与依赖关系

5.设置set办法拦挡赋值行为并触发依赖

6.应用effectWatch办法保留依赖

这就实现了一个根本的reactive办法,实现了响应式关系。
全副代码:

// let a = 10;// let b;// update()// function update() {//     b = a + 10;//     console.log(b)// }// a = 20;// update();// vue3的reactivity模块// const { reactive, effect } = require("@vue/reactivity");// let a = reactive({//     value: 10,// });// let b;// effect(() => {//     b = a.value + 10;//     console.log(b);// });// a.value = 20;// 响应式库let currentEffect; // 全局依赖class Dep {    constructor(val) {        this.effects = new Set(); // 依赖列表        this._val = val;    }    get value() {        this.depend();        return this._val;    }    set value(newVal) {        this._val = newVal        this.notice()    }    // 收集依赖    depend() {        if (currentEffect) this.effects.add(currentEffect)    }    // 触发依赖    notice() {        this.effects.forEach((effect) => {            effect()        })    }}// 收集依赖function effectWatch(effect) {    currentEffect = effect;    // 绑定依赖时先触发一次依赖    effect();    currentEffect = null;}// const dep = new Dep(10)// let b;// effectWatch(() => {//     b = dep.value + 10;//     console.log(b)// })// dep.value = 20;// vue3 proxyconst targetMap = new Map(); // 存储所有的依赖映射关系function getDepta(target, key) {    let depsMap = targetMap.get(target) // 获取对象的所有依赖    if (!depsMap) {        depsMap = new Map()        targetMap.set(target, depsMap)    }    let dep = depsMap.get(key) // 获取对应key的所有依赖    if (!dep) {        dep = new Dep();        depsMap.set(key, dep)    }    return dep;}function reactive(obj) {    return new Proxy(obj, {        get(target, key) {            const dep = getDepta(target, key);            dep.depend() // 收集依赖            return Reflect.get(target, key)        },        set(target, key, value) {            const dep = getDepta(target, key);            const relust = Reflect.set(target, key, value)            // 触发依赖            dep.notice();            return relust;        }    })}const user = reactive({    age: 19,    aaa: 30})let b, c;effectWatch(() => {    console.log('reactive')    b = user.age + 10    console.log(b)})effectWatch(() => {    console.log('reactive1111')    c = user.aaa - 5    console.log(c)})user.age = 20user.aaa = 20