js 数据响应

class Dep {
    // 依赖类,用来收集和触发
    constructor() {
        // 生成一个集合,用来存放依赖,之所以的用set是因为,set里的数组,数据不会重复
        this.subscribers = new Set();
    }

    depend() {//收集
        if (activeEffect) this.subscribers.add(activeEffect)
    }

    notify() {//触发 
        this.subscribers.forEach(effect => effect())
    }

}

let activeEffect = null
function watchEffect(effect) {
    activeEffect = effect
    effect()
    activeEffect = null
}


function reactive(obj){
    Object.keys(obj).forEach(key=>{
        let dep = new Dep()
        let value = obj[key]
        Object.defineProperty(obj,key,{
            get(){
                // 在get的时候,进行依赖收集
                dep.depend()
                return value
            },
            set(newValue){
                // set赋值,并触发
                value = newValue
                dep.notify()
            }
        })
    })


    // 加工完成,返回
    return obj
}






//测试代码
let person = reactive({age:18,name:"test"})

let school = reactive({name:"小黑学院"})


watchEffect(function(){
    console.log(person.age,school);  
})

watchEffect(function(){
    console.log(person.name);
})
watchEffect(function(){
    console.log(school.name);
})

// person.age = 20
school.name = "小白学院"

缺点,收集的依赖,在外面就拿不到了,只是做初步记录,做出以下修改就可完善一点,至少在外面可以拿到了

class Dep {
    // 依赖类,用来收集和触发
    constructor() {
        // 生成一个集合,用来存放依赖,之所以的用set是因为,set里的数组,数据不会重复
        this.subscribers = new Set();
    }

    depend() {//收集
        if (activeEffect) this.subscribers.add(activeEffect)
    }

    notify() {//触发 
        this.subscribers.forEach(effect => effect())
    }

}

let activeEffect = null
function watchEffect(effect) {
    activeEffect = effect
    effect()
    activeEffect = null
}

// Map({key: value}): key是一个字符串,map强引用
// WeakMap({key(对象): value}): key是一个对象, 弱引用
const depMap = new WeakMap()//收集每个对象的key有哪些依赖===>{obj:{name:depClass}}
function getDep(obj,key){
    let deps = depMap.get(obj)
    if(!deps){
        deps = new Map()
        depMap.set(obj,deps)
    }

    let dep = deps.get(key)
    if(!dep){
        dep = new Dep()
        deps.set(key,dep)
    }
    return dep
}

function reactive(obj){
    Object.keys(obj).forEach(key=>{
        let dep = getDep(obj,key)
        let value = obj[key]
        Object.defineProperty(obj,key,{
            get(){
                // 在get的时候,进行依赖收集
                dep.depend()
                return value
            },
            set(newValue){
                // set赋值,并触发
                value = newValue
                dep.notify()
            }
        })
    })


    // 加工完成,返回
    return obj
}







let person = reactive({age:18,name:"test"})

let school = reactive({name:"小黑学院"})


watchEffect(function(){
    console.log(person.age,school);  
})

watchEffect(function(){
    console.log(person.name);
})
watchEffect(function(){
    console.log(school.name);
})

// person.age = 20
school.name = "小白学院"

console.log(depMap);

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值