【手把手教你搓Vue响应式原理】(一)初识Vue响应式

大家好,我是 辉夜真是太可爱啦 。这是我最近在写的【手把手教你搓Vue响应式原理】系列,本文将一步步地为你解开vue响应式原理的面纱。由于本人也是在写这篇文章的过程中不断试错,不断学习改进的,所以,本文同样很适合和我一样的初学者。和 Vue 的设计理念如出一辙,那就是渐进增强。

MVVM

在讲这个之前,首先要明白一点,这个所谓的响应式,其实本身就是对 MVVM 的理解。

MVVM 其实就是所谓的 Modal View ViewModal。

简单理解,就是你的 data 中的数据,和 template 模板中的界面,本身就是两个东西。

但是, Vue 给你做了一层中间的 ViewModal,让视图上的改变能反映到 data 中, data 中的改变能反映到视图上。

image.png

在这个反映过程中,ViewModal就是视图和数据的一个桥梁。

非侵入式和侵入式

同样是让 a + 1 。

在Vue 中,这个桥梁是你看不见的,因为 Vue 都帮你完成了视图和数据的变化传递。

而 React 就是侵入式的,因为要显式地声明 setState ,通过它,来设置变量的同时,设置视图的改变。

image.png

所以,所谓的侵入式,其实就是对于桥梁的侵入。

Vue的神奇之处

所以, Vue 的神奇之处就在于,不需要我们手动地显示调用 setState ,也就是这个桥梁, Vue 已经帮我们桥接上了。

要让 data 改变的同时,视图也发生改变,所以,问题的所在,就是我们需要监听,什么时候,这个变量发生了变量。

然而, ES5 中,就有那么一个特性,可以做到对于数据的劫持(监听)。

它就是 Object.defineProperty 。

Object.defineProperty

Object.defineProperty( obj, prop, descriptor ) 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象,与此同时,它可以对对象的一些额外底层的属性进行设置。例如可以设置writable , enumerable , configurable 等属性。

后面的额外属性设置,才是我们使用它的重点。

但是,我们使用的不是上面的几个属性,最主要的还是它的 get set ,可以对属性值的获取和设置操作进行拦截。

  • get

get主要是可以对值的获取进行拦截,,它必须要传入一个 return ,并且,该函数的返回值会被用作属性的值。我们可以来看一个例子:

image.png
let a={name:'jack'};
Object.defineProperty(a,'name',{
  get(){
    return '你已经被拦截了!';
  },
})
console.log(a.name);    //你已经被拦截了!

由于设置了 get ,所以,输出 a.name 的时候直接会被拦截,走 get() 中的 return 所以,此时,a.name 的值应该是 你已经被拦截了!。

  • set

set主要是可以对值的设置进行拦截,该方法会接受一个参数,那就是被赋予的新值。我们可以来看一个例子:

let a={name:'jack'};
Object.defineProperty(a,'name',{
  set(newValue){
    console.log('你正在设置值' + newValue);
  }
})
a.name='bob';   // 你正在设置值bob

由于设置了 set ,所以,设置值的时候会被拦截,走 set() 中的方法。

文末总结

所以, Vue 能自动获取data中的改变,反映到视图的原因,就是有对于变量的获取和设置的劫持,当变量发生改变的同时, Vue 能在第一时间知道,并且对视图做出相应的改变操作。

而这把钥匙就是 Object.defineProperty 。

文章参考

【尚硅谷】Vue源码解析之数据响应式原理

Object.defineProperty() - MDN

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容