Vue响应式系统原理并实现一个双向绑定

这一章就着重讲两个点:

  • 响应式系统如何收集依赖
  • 响应式系统如何更新视图 我们知道通过Object.defineProperty做了数据劫持,当数据改变的时候,get方法收集依赖,进而set方法调用dep.notify方法去通知Watcher调用本身update方法去更新视图。那么我们抛开其他问题,就讨论getnotifyupdate等方法,直接上代码:

get( )

 get: function reactiveGetter () {const value = getter ? getter.call(obj) : valif (Dep.target) {dep.depend()if (childOb) {childOb.dep.depend()if (Array.isArray(value)) {dependArray(value)}}}return value} 

我们知道Dep.target在创建Watcher的时候是null,并且它只是起到一个标记的作用,当我们创建Watcher实例的时候,我们的Dep.target就会被赋值到Watcher实例,进而放入target栈中,我们这里调用的是pushTarget函数:

// 将watcher实例赋值给Dep.target,用于依赖收集。同时将该实例存入target栈中
export function pushTarget (_target: ?Watcher) {if (Dep.target) targetStack.push(Dep.target)Dep.target = _target
} 

那我们继续执行到if (Dep.target)语句的时候就会调用Dep.depend函数:

 // 将自身加入到全局的watcher中depend () {if (Dep.target) {Dep.target.addDep(this)}} 

那下面的childOb是啥东西呢?

 let childOb = !shallow && observe(val) 

我们通过这个变量判断当前属性下面是否还有ob属性,如果有的话继续调用Dep.depend函数,没有的话则不处理。 我们还需要处理当前传入的value类型,是数组属性的话则会调用dependArray收集数组依赖

// 收集数组依赖
function dependArray (value: Array<any>) {
for (let e, i = 0, l = value.length; i < l; i++) {e = value[i]e && e.__ob__ && e.__ob__.dep.depend()if (Array.isArray(e)) {dependArray(e)}
}
} 

那么收集依赖部分到这里就完了现在进行下一步触发更新

set( )

 set: function reactiveSetter (newVal) {const value = getter ? getter.call(obj) : val/* eslint-disable no-self-compare */// 判断NaN的情况if (newVal === value || (newVal !== newVal && value !== value)) {return}/* eslint-enable no-self-compare */if (process.env.NODE_ENV !== 'production' && customSetter) {customSette
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值