Vue响应式实现原理

前言

以前在学习Vue框架的时候只管着用,并没有考虑太多Vue这玩意是怎样实现的,总之用着顺手就行,很多底层原理的东西并没有去考究那么多。到后来发现,遇到了许多问题,上网一搜也就知道个解决办法,对于一些问题是怎么产生的很多答案也都不能准确说出,然后对于Vue这个框架使用时间也不短了,于是决定找时间研究一下Vue的底层原理,形成一系列文章供日后参考。

响应式原理

首先是何为响应式,网上书上一大堆解释,就不套那些晦涩的文字了,我个人最直观的理解就是“感知数据变动”这6个字,硬要说复杂点就是能够根据数据的变动执行一系列的操作,没了,简单明了。

Vue感知数据变动的方式

Vue感知数据变动的方式其实有两种,好像也不能说作两种,而是对于对象类型以及数组类型,Vue的感知方式是有所不同的。对于对象而言,能够检测到对象变化的只有Object.defineProperty,如果要用另外的方法的话也只有ES6中的proxy了,使用了对象的getter和setter之后相当于对使用对象进行了一层拦截,以此方法来感应对象的变化;另一方面,对于数组,Vue中则使用了更为粗暴的拦截方法,通过原型链的方式重写了所有会更改原数组的方法(push,pop,shift,unshift,splice,sort,reverse),在重写的方法里作响应处理。

Object响应式

与react和angular不同,Vue是相对而言能够感应到数据变化粒度最细的框架了,这就得益于Vue的依赖收集,对于对象的依赖收集,Vue是在对象的get中做的,每当对象被读取时进行一次依赖收集,保存在Dep类中的subs数组中,然后当该对象发生改变时循环触发subs中收集到的依赖的update方法。
对象依赖收集关键代码:

//  将对象转换成响应式对象方法,此vue里对象的响应式主要是通过这个方法实现的
/**
* Define a reactive property on an Object.
*/
export function defineReactive (
obj: Object,
key: string,
val: any,
customSetter?: ?Function,
shallow?: boolean
) {
   
/*
创建依赖,当触发getter时调用类方法addSub把依赖搜集进去,
这里所说的依赖其实是watcher,在vue中当一个对象被调用触发setter时会首先
通知到dep里面收集的watcher然后再由各个watcher去通知
更新dom(这其中的步骤还是很多的,例如vnode的diff就是一个很复杂的步骤)
*/
const dep = new Dep()  

const property = Object.getOwnPropertyDescriptor(obj, key)
if (property && property.configurable === false) {
   
  return
}

// cater for pre-defined getter/setters
const getter = property && property.get
if (!getter && arguments.length === 2) {
   
  val = obj[key]
}
const setter = property && property.set

let childOb = !shallow && observe(val)
/*
调用defineProperty设置对象的getter和setter
*/
Object.defineProperty(obj, key, {
   
  enumerable: true,
  configurable: true,
  get: f
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值