Responsive是一种面向数据流和变化传播的编程范式。这意味着静态或动态数据流可以很容易地用编程语言表达,相关的计算模型将通过数据流自动传播变化的值。Vue2+版本基于Object.defineProperty实现了双向数据绑定,即当数据改变时,视图也随之改变。Object.defineProperty用法:letobj={}Object.defineProperty(obj,'value',{get(){return1},set(newValue){console.log('set')value=newValue}})//console//obj.value=>1//obj.value=2=>set假设由x和y表示,当x变化时,y也随之变化//将x转换成可以监听变化的对象letx=ref(1)letref=initValue=>{letvalue=initValuereturnObject.defineProperty({},'value',{get(){returnvalue},set(newValue){value=newValueactive()//x变化时触发y变化}})}//当x变化时,y随之变化(f函数模拟变化)letf=n=>n*100+100letactiveletwatch=(cb)=>{active=cbactive()//在开始时触发一次}watch(()=>{y=f(x.value)console.log(y)})x.value=2//如果x改变也会导致z改变,现在300,那么你需要添加另一个活动。因此,由于一个变量的修改会涉及到模板中多个地方的变化,所以需要收集因变量,并添加一个classDepclassDep{constructor(){//Set数据结构类似于数组,但是成员是唯一的//通过newthis.deps=newSet()生成Set数据结构}depend(){//依赖集合if(active){//通过add()方法向Set结构添加成员this.deps.add(active)}}notify(){//触发this.deps.forEach(dep=>dep())}}修改watch函数,避免重复收集。在get中收集依赖并在set中触发最终实现://如果x改变,y和z都会改变letxletyletzletfy=n=>n*100+100letfz=n=>n+1letactiveletwatch=(cb)=>{active=cbactive()active=null//避免重复收集}//当X变化时,会引起y和z的变化,一次变化引发多次变化classDep{constructor(){//设置数据结构类似于数组,但成员是唯一的//通过newthis.deps=newSet()}depend(){//依赖集合if(active){//为Set结构添加成员通过add()方法this.deps.add(active)}}notify(){//触发this.deps.forEach(dep=>dep())}}letref=initValue=>{letvalue=initValueletdep=newDep()returnObject.defineProperty({},'value',{get(){dep.depend()返回值},set(newValue){value=newValuedep.notify()}})}x=ref(1)watch(()=>{y=fy(x.value)console.log(y)})watch(()=>{z=fz(x.value)console.log(z)})x.value=2/*控制台打印20023003*/
