持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第22天,点击查看活动详情
4.2响应式数据的基本实现
接着上文,如何让一个数据变为响应式数数据呢,我们吧响应式数据拆分成这两个过程
- 当副作用函数执行时,触发变量的
读取 修改变量时,触发相应的操作
也就是说,要实现一个响应式变量,我们应当先能拦截到变量的读取和修改
同样,当我们修改变量时,这个流程应当颠倒过来
首先,我们需要一个Set来存储effect,因为Set可以避免重复,同时我们定义一个原始值
const effects = new Set()
// 原始值
const data = {text:'hello'}
说到拦截读取和修改,大部分人第一反应Object.defineProperty,这也是vue2用的办法,这个方法虽然兼容性比较好,但也存在一些问题,想必熟悉vue2的你都很清楚了,但是这本书是vue3的,我们自然也要选择类似vue3的写法。
在ES6中,新增了Proxy,字面意思就是代理,功能就是代理对这个对象的任何操作。具体的API大家可以参考这个
阮一峰ES6-Proxy
接着上文,我们开始通过Proxy写一个响应式数据.
在读取的时候,我们收集副作用函数,当修改的时候,我们运行副作用函数。
const obj = new Proxy(data,{
get(target,key){
effects.add(effect)
return target[key]
},
set(target,key,value){
target[key] = value
effect.forEach(fn=>fn())
return true
}
})
这样就简单的实现了响应式,我们可依在F12里这样简单的测试一下
function effect = ()=>{
document.body.innerHTML = obj.text
}
effect()
setTimeout(()=>{obj.text='1234'},1000)
当然,这只是一个最简单demo,里面有很多问题,比如这里的effect函数是不能变成其他名字的,这就叫硬编码,当然时不可取。 下一篇里,我们会改掉这一点