目录
1.目标:
2.原理
3.实现代码
4.小结:
1.目标:
假设我现在有一个对象obj
let obj = {text:"hello 小明"}
还有一个函数effect
function effect (){
//看作是页面上的值
=
}
我们希望修改值 = "hello vue3"时,effect函数页执行,使得页面数据发生变化
想要的效果是修改的值,页面也跟着变化,这就是响应式。
再明确一下目标:修改对象的值,使页面自动更新我们修改的最新值(数据)
2.原理
vue2使用的是函数实现,而vue3使用的proxy代理对象实现,这里使用proxy。
完成上述的目的有两个重要的信息:
第一个时当执行effect的时候会触发的读取操作
第二个是当修改的时候会触发的设置操作
当然,重头戏就是代理对象proxy来实现了
3.实现代码
const bucket = new Set() //类数组结构,用来存储effect函数
const data = {text:"hello xiaoming"} //原始数据
const obj = new Proxy(data,{
//拦截读取操作
get(target,key){
//将effect添加到bucket
(effect)
//返回属性值
return targrt[key]
},
//拦截设置操作
set(target,key,newval){
//设置属性值
target[key] = newval
//把effect从bucket中取出来并执行
(fn => fn())
//返回true代表设置成功
return true
}
})
接下来执行以下看效果
function effect(){
=
}
effect()//执行
//过1秒后执行修改,看看页面是否变化
setTimeout(()=>{
= "看看修改成功了没有"
},1000)
ps:肯定有人疑问为啥bucket是干嘛的,其实就是为了实现页面变化,细品一下。
这个bucket的作用就是修改dom元素使页面及时变化
要理解proxy”代理“这两个字,举个简单的例子,本来有一个苹果,但是想要的是苹果汁,那么在苹果变成苹果汁的过程可以看作被代理了,这么理解的话,proxy就很容易理解了。
4.小结:
到目前为止,响应式数据完成了,但是不够完善,但这就是响应式原理的最简单实现代码。后续我会写一个完善版的响应式文章。
在上面,我们创建了一个存储副作用的桶bucket,他是set类型。接着定义原始数据类型data,obj是原始数据的代理对象,我们分别设置了get 和 set拦截函数,用于拦截和读取操作。当读取属性时将副作用effect函数放到桶里,即(effect),然后返回属性值。当设置属性值时先更新原始数据,然后将副作用函数从桶里取出来并且执行,这样我们就实现了响应式数据。