vue 的响应式框架 (1.0)
思路:属性发生变化时,调用依赖这些属性的函数
一、实现的过程需要解决以下一些问题
1.如何追踪属性发生了变化
2.如何知道该属性被哪些依赖使用
3.如何执行依赖的函数
4.如何避免重复执行依赖的函数
二、基础知识
object.defineProperty(obj, prop, descriptor)方法介绍
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 var obj = { name : '张三' , age : 20 } object.defineProperty (obj,name ){ get :function ( ){ console .log ('有人读取了name属性' ) return obj.name } set function (val ){ obj.name = val console .log ('有个家伙在给name属性赋值' ) } }
去重
1 2 3 4 5 6 7 let funcs = new Set ()let funcs = []if (!funcs.includes (func)) { funcs.push (func) }
三、难点
此时我们已经解决了问题1和问题4,也知道了依赖函数应该在set中执行。那么如何知道属性被哪些依赖使用呢?
1 2 3 4 5 window .__func = func1 func1 () window .__func = null
四、实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 function Observer (obj ) { for (const key in obj){ let intervalValue = obj[key] let observers = new Set () defineProperty (obj, key, obj[key] ){ get : function ( ){ if (window .__func ){ observers.add (window .__func ) } return intervalValue }, set : function (val ){ console .log ('有人修改了' + key + '属性,我要去通知我的订阅者了' ) obj[key] = val observers.forEach (observer => observer ()) } } } } function autoRun (fn ){window .__func = fnfn ()window .__func = null } autoRun (func1 ())autoRun (func2 ())