4.2 响应式数据的基本实现
关键词
- 读取操作(赋值给别人)
- 设置操作(改变值本身)
- 拦截对象的读取和设置
- ES2015之前 Object.defineProperty (vue2)
- ES2015+ 对象Proxy (vue3)
笔记
-
思路图
-
代码实现 Proxy 实现
// 第一步 建立存储桶 存储副作用函数的桶
const bucket = new Set()
// 第二步 定义原始数据
const data = { text: 'hello world'}
// 第三步 对原始数据进行代理
const obj = new Proxy(data,{
// 第四步 设置get函数 拦截读取操作
// 这里的target 默认为传进来的第一个参数 即原始数据的值
// key 为对应操作对象的属性
get(target,key){
// 将副作用函数 effect 存储到桶中
bucket.add(effect)
// 返回属性值
return target[key]
},
// 第五步 设置set函数 拦截设置操作
// newVal 为新设置的值
set(target,key,newVal){
// 设置属性值
target[key] = newVal
// 将副作用函数 effect 从桶中取出并执行
bucket.forEach(fn => fn())
// 返回 true 表示操作成功
return true
}
})
总结:
- 第一步 建立Set存储桶
- 第二步 定义原始数据
- 第三步 对原始数据进行代理 new Proxy()
- 第四步 设置get函数 拦截数据的读取操作 此时将副作用函数存入Set存储桶中 再返回值
- 第五步 设置set函数 拦截数据的设置操作 先重新赋值 然后依次执行Set存储桶中的副作用函数 for循环依次执行
代码测试
// 副作用函数
function effect() {
document.body.innerText = obj.text
}
// 执行副作用函数,触发读取
effect()
// 1 秒后修改响应式数据
setTimeout(()=>{
obj.text = 'hello vue3' // 触发设置操作
},1000)