响应式原理实现

发布时间 2023-09-06 17:25:38作者: KooTeam

响应式原理实现

 1 // 保存当前需要收集的响应式函数
 2 let activeReactiveFn=null
 3 class Depend{
 4     constructor(){
 5         this.rectiveFns=new Set()
 6     }
 7     depend(){
 8         if(activeReactiveFn){
 9             this.rectiveFns.add(activeReactiveFn)
10         }
11     }
12     notify(){
13         this.rectiveFns.forEach(fn=>{
14             fn()
15         })
16     }
17 }
18 //封装一个响应式的函数
19 function watchFn(fn){
20     activeReactiveFn=fn
21     fn()
22     activeReactiveFn=null
23 }
24 // 封装一个获取depend函数
25 const targetMap=new WeakMap()
26 function getDepend(target,key){
27     //根据target对象获取map的过程
28     let map=targetMap.get(target)
29     if(!map){
30         map=new Map()
31         targetMap.set(target,map)
32     }
33     //根据key获取depend对象
34     let depend=map.get(key)
35     if(!depend){
36         depend=new Depend()
37         map.set(key,depend)
38     }
39     return depend
40 }
41 
42 function reactive(obj){
43     //监听对象的属性变量:Proxy(vue3)/Object.defineProperty(vue2)
44     //vue3
45     // return new Proxy(obj,{
46     //     get(target,key,receiver){
47     //         const depend=getDepend(target,key)
48     //         depend.depend()
49     //         return Reflect.get(target,key,receiver)
50     //     },
51     //     set(target,key,newValue,receiver){
52     //         Reflect.set(target,key,newValue,receiver)
53     //         let depend=getDepend(target,key)
54     //         depend.notify()
55     //     }
56     // })
57     //vue2
58     Object.keys(obj).forEach(key=>{
59         let value=obj[key]
60         Object.defineProperty(obj,key,{
61             get(){
62                 const depend=getDepend(obj,key)
63                 depend.depend()
64                 return value
65             },
66             set(newValue){
67                 value=newValue
68                 let depend=getDepend(obj,key)
69                 depend.notify()
70             }
71         })
72     })
73     return obj
74 }
75 
76 //对象的响应式
77 const obj=reactive({
78     name:'koo',
79     age:18
80 })
81 
82 watchFn(function(){
83     console.log('hello world',obj.name)
84 })
85 
86 obj.name='john'