Vue3响应式原理学习
-
原理概括
Vue3
使用Proxy
劫持数据的修改和读取- 使用
Reflect
API修改和读取数据 - 在读取属性时,记录是哪个函数读取的,每一个属性对应一个
Set
对象 - 在属性被修改时,使用
forEach
遍历调用这些函数,完成修改渲染
-
原理参考图
-
实现代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>响应式学习</title> </head> <body> <div>F12打开修改user、user2</div> <div id="app"></div> <div id="app2"></div> <div id="app3"></div> <script> let activeEffect; const effect=(fn)=>{ const _effect=()=>{ fn() } activeEffect=_effect _effect() } let targetMap=new WeakMap() const track=(target,key)=>{ let depsMap=targetMap.get(target) if( !depsMap ){ depsMap=new Map() targetMap.set(target,depsMap) } let deps=depsMap.get(key) if( !deps ){ deps=new Set() depsMap.set(key,deps) } deps.add(activeEffect) } const trigger=(target,key)=>{ let depsMap=targetMap.get(target) let deps=depsMap.get(key) deps.forEach(effect=>effect()) } const reactive=(target)=>new Proxy(target,{ get(target,key,receiver){ track(target,key) const res= Reflect.get(target,key,receiver) if( res!==null && typeof res==="object" ){ return reactive(res) } return res }, set(target,key,value,receiver){ const res=Reflect.set(target,key,value,receiver) trigger(target,key) return res } }) const user=reactive({ name:'xxcheng', age:18, sex:'男', book:{ name:'海底两万里' } }) effect(()=>{ document.querySelector('#app').innerText=`app:name:${user.name},age:${user.age},sex:${user.sex},book.name:${user.book.name}`; }) const user2=reactive({ name:'jpc', age:11, sex:'男' }) effect(()=>{ document.querySelector('#app2').innerText=`app2:name:${user2.name},age:${user2.age},sex:${user2.sex}`; }) effect(()=>{ document.querySelector('#app3').innerText=`app3:name:${user2.name},age:${user2.age},sex:${user2.sex}`; }) </script> </body> </html>
-
运行测试
-
修改前
-
将
user.name
修改为www123
-
将
user.book.name
修改为喜羊羊与灰太狼
-
将
user2.age
修改为999
-
-
参考链接
本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。
终于到了你最爱的vue3环节