响应式数据的基本实现

74 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 14 天,点击查看活动详情 响应式数据的基本实现

副作用函数

什么是副作用函数

当一个函数直接或者间接的影响其他函数的执行,这是我们就说这个函数产生了副作用。

function effect() {
    document.body.innerText = 'hellow vue3'

}

上面这个函数就是副作用函数。为什么呢,因为body变量其他任何函数也能够读取到也能够设置他的值。

响应式数据

const obj = {text: 'hello vue'}
function effect() {
    // effect函数的执行会读取obj.text的内容。
    document.body.innerText = obj.text
}

obj中的text变化的时候,使用到obj.text 的相关函数全部变化,这样我们就说obj.text是响应式的数据。

响应式的基本实现

由此我们可以得到最简单的响应式实现。即在获取数据的时候getter,收集所有用到该数据的函数,当setter数据的时候,将收集到的所有数据函数的集合遍历执行一遍。

let callFunction 
function observeFuction (fn) {
    callFunction = fn
    fn()
}

// 将 定义设置innerText的函数 用observeFuction包裹起来. 这句话执行后就将函数保存到了全局的callFunction变量上面
observeFuction (() => {
    document.body.innerText = obj.text
))


//执行effect函数
effect()

// 其他函数修改了obj.text的值。
setTimeout(()=> {
    obj.text = 'hello vue3'
}, 1000)

这里面的关键是在调用getter方法的时候如何获取调用的函数实例。 所以这里我们就要引入一个新的函数observeFuction

实现响应式



const collectionEffect = newSet()
const data = {text: 'hello world'}
const obj = new Proxy(data, {
    // 所有获取obj.text的时候收集依赖
    get(target,key) {
        if(callFunction) {
            // 收集依赖
            collectionEffect.add(callFunction)
        }
        return target[key]
        
    }, 
    set(target, key, newValue) {
        target[key] = newValue
        // 遍历收集依赖的集合,调用响应的使用到obj.text 的函数,消除副作用,实现响应式
        collectionEffect.forEach(fn => fn())
        return true
    }

})

当在浏览器运行的时候我们看到当定时一秒后改变text值的时候,浏览器展示的文案也跟着变了。 至此一个简单的响应式数据模型就实现了

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 14 天,点击查看活动详情