我是如何看Vue源码的(2),前端面试

接着来看一种最典型的watcher行为,在/src/core/instance/lifecycle.js中的moundComponent方法中,可以看到一个实例化watcher的方法

new Watcher(vm, updateComponent, noop, {

before () {

if (vm._isMounted && !vm._isDestroyed) {

callHook(vm, ‘beforeUpdate’)

}

}

}, true /* isRenderWatcher */)

可以看到,他将updateComponent(可以抽象为渲染行为)传给Watcher,而在Watcher的实例化中,将会执行此方法,当然在执行之前,pushTarget(this),将这个watcher挂载到公共变量上而后开始执行渲染行为,

class Watch {

constructor(…) {

if (typeof expOrFn === ‘function’) {

this.getter = expOrFn

}

this.get();

}

get() {

pushTarget(this) // 挂载行为至公共Target

value = this.getter.call(vm, vm) // 开始执行行为,之所以会有返回值是为了computed服务

popTarget() // 取消挂载,避免下次读取变量时又会绑定此行为

}

}

此时,如果此行为读取了某个响应式变量,那么该变量的getter将会存储公共变量target,当行为完成后就会取消行为的挂载,这个时候我们再回过头来看前面的defineReactive的逻辑

function defineReactive(obj, key) {

const dep = new Dep(); // 每个数据都有一个自己的存储列表

const getter = property && property.get

const setter = property && property.set

Object.defineProperty(obj, key, {

enumerable: true,

configurable: true,

get: function reactiveGetter () {

const value = getter ? getter.call(obj) : val

if (Dep.target) { // 判断公共变量中是否挂载了行为(watcher)

dep.depend() // 将行为(watcher)加入dep(即此变量的存储行为列表)

}

return value

},

set: function reactiveSetter(newVal) {

const value = getter ? getter.call(obj) : val

if (newVal === value || (newVal !== newVal && value !== value)) {

return // 判断变量没有变化,则直接返回(后两者判断则是因为NaN!==NaN的特性)

}

if (setter) {

setter.call(obj, newVal) // 开始

} else {

val = newVal

}

dep.notify() // 通知自己这个数据的存储列表,数据发生改变,需要重新执行行为(watcher)

}

});

}

这个时候就很清晰明了了,这就是很多博客文章所说的依赖收集,变量在get时通过公共变量Target收集依赖(也就是本文所说的行为),在set时,即变量数据发生改变时,触发更新notify;

2.2.2 Computed

前文有大致介绍computed的实现,实际上在介绍完Wacher之后就可以来详细介绍了,计算属性computed并没有实际的变量,他通过原型链覆盖创造了一个变量指向(src/core/instance/state.jsinitComputed),回忆一下computed的两种写法

‘fullName’: function() {

return this.firstName + this.secondeName;

}

‘fullName’: {

get: function () {…},

set: function() {…},

}

我们再来看一下initComputed

function initComputed (vm:

  • 22
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值