vue源码 - 数据响应式原理 - 入口、observer、defineReactive、收集依赖

资源

各种进阶资源 + 联系方式请看下方链接
资源

通过查看源码解决下面问题

  • vm.msg = { count: 0 } 重新给属性赋值,是否是响应式的?
  • vm.arr[0] = 4, 给数组元素赋值,视图是否会更新
  • vm.arr.length = 0, 修改数组的length视图是否会更新
  • vm.arr.push(4), 视图是否会更新

响应式处理的入口

src/core/instance/init.js
  • initState(vm) vm状态的初始化
  • 初始化了_data、_props、methods等
src/core/instance/state.js在这里插入图片描述

在这里插入图片描述

src/core/observe/index.js

在这里插入图片描述
在这里插入图片描述

  • defineReactive
    在这里插入图片描述
  • 依赖收集 - 对应上图get中逻辑
    我们首先看Dep.target是从哪个位置赋值过来的
    首先点击Dep.target 发现跳转到了src/core/observer/dep.js中
    在这里插入图片描述
    然后我们发现target是一个watcher对象,此时我们点击warcher 跳转到src/core/observer/watcher.js中 然后我们发现了pushTarget方法传入this也就是把当前watcher对象传入
    在这里插入图片描述
    在这里插入图片描述
    此时我们再来看 dep.depend() = dep.target.addDep(this(当前dep对象)) = watcher.addDep(dep对象)
    在这里插入图片描述
    在这里插入图片描述
    收集依赖的过程就是通过模版中变量属性对应的dep对象,来收集对应组件对应的watcher,收集到dep对应的subs数组中来具体调试步骤如下
  1. src/core/instance/lifecycle.js 中的 new Watcher方法
  2. src/core/observer/watcher.js 中的 get()函数的pushTarget(this)中 dep.target = watcher
  3. this.getter.call(vm, vm)
  4. src/core/instance/lifecycle.js 中的 updateComponent = () => {
    vm._update(vm._render(), hydrating)
    } _render方法是生成虚拟dom然后再把生成的虚拟dom传递给_update 在处理虚拟dom的时候 用到了对应的data中属性时 会出发get方法
  5. src/core/observer/index.js 中defineReactive的get方法中调用dep.depend方法中收集依赖,把dep对象添加到watcher的依赖中
  6. src/core/observer/watcher.js 中的addDep中判断newDepIds中是否已经有了当前的dep对象,如果没有的话才会把当前dep对象的id添加到newDepIds中,dep对象添加到newDeps中。
  7. 调用src/core/observer/dep.js 中的addSub方法把当前的watcher对象添加到dep的subs数组中来
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值