数据响应原理-----2.defineReactive()

415 阅读2分钟

写在前面:笔记来源于www.bilibili.com/video/BV1iX… 侵删

reactive表示的是响应式

1.为啥要定义defineReactive()函数?

实际上是因为Object.defineProperty()函数不好用\

看看get函数:

image.png 就是说get函数必须要有返回值才行: 我们来看看上一个笔记的遗留问题:

image.png 我们刚才说到get函数必须要拥有返回值才可以,那我们给它加上返回值来看看:

image.png

封装成函数之后,就不用去特意声明一个

image.png 现在这个7才能被正常显示出来。没有什么问题。

再看看set函数:

image.png 就是这个意思:

image.png

image.png 发现神奇的事情了嘛?
你试图改变obj.b,但是最终得到的数据是10还是7?
依然是7
就是说你的赋值是失败的
为啥呢???
因为:

image.png 当你访问obj.b的时候,你依然会去调用get函数,拿到的依然是return的结果。10仿佛没有来过。
为了解决这个问题,我们设置了一个变量temp

image.png 结果:

image.png

再次做个测试:

image.png

结果:

image.png

小总结:

为了保证set和get数据的实时性,我们引入了一个中间变量temp用来周转(重要)

接下来来看defineReactive()函数

临时变量看起来不美观,所以我们将它封装到函数中去,利用函数的闭包来完成功能。
那啥是闭包呢,闭包一定要有内外两层函数嵌套的
get()和set()是内层
defineReactive()是外层

var obj = {};

function defineReactive(data,key,val){

Object.defineProperty(data,key,{

// 可以枚举

enumerable:true,

// 可以被配置,比如可以被delete

configurable:true,

get(){

console.log('你试图访问obj的a属性')

return val

},

set(newValue){

console.log('你试图改变obj的a属性',newValue)

if(val == newValue){

return

}

val = newValue

}

})

}

defineReactive(obj,'a',10)

console.log(obj.a)

obj.a = 111

obj.a ++

console.log(obj.a)


感觉代码不大好看:

image.png 这个思维绝绝子!!!

总结:

Object.defineProperty()函数中的get()和set()是vue中的MVVM能够实现:数据一更改,视图就跟着更改的效果的原因。
但是这里需要一个中转变量去接收去更改
为了优雅地表示出这个中转变量,我们将它封装成了一个函数;也就是defineReactive()函数了