解读 Vue 之 Reactive

本文深入探讨Vue的响应式原理,涉及Reactive、Watcher、Dep和Observer等关键概念。文章阐述了Vue如何将数据包装成可观测类型,当数据变化时能自动更新视图。在初始化组件时,通过initData、initComputed和mountComponent等步骤,实现数据的reactive化,创建依赖关系并确保数据变更时触发相应的更新操作。
摘要由CSDN通过智能技术生成

前言

在一篇文章中简单讲了 vue 是如何把模板解析成 render function 的,这一篇文章就来讲讲 vue 是如何把数据包装成 reactive,从而实现 MDV(Model-Driven-View) 的效果。

先说明一下什么叫 reactive,简单来说,就是将数据包装成一种可观测的类型,当数据产生变更的时候,我们能够感知到。

而 Vue 的相关实现代码全部都在 core/observer 目录下,而要自行阅读的话,建议从 core/instance/index.js 中开始。

在开始讲 reactive 的具体实现之前,先说说几个对象:Watcher、Dep、Observer。

Watcher

Watcher 是 vue 实现的一个用于观测数据的对象,具体实现在 core/observer/watcher.js 中。

这个类主要是用来观察方法/表达式中引用到的数据(数据需要是 reative 的,即 data 或者 props)变更,当变更后做出相应处理。先看一下 Watcher 这个类的入参:

vm: Component,
expOrFn: string | Function,
cb: Function,
options?: Object

解释一下这几个入参是干嘛的:

  • vm:当前这个 watcher 所属的 VueComponent。
  • expOrFn:需要监听的 方法/表达式。举个例子:VueComponent 的 render function,或者是 computed 的 getter 方法,再或者是abc.bbc.aac这种类型的字符串(由于 vue 的 parsePath 方法是用 split('.') 来做的属性分割,所以不支持abc['bbc'])。expOrFn 如果是方法,则直接赋值给 watcher 的 getter 属性,如果是表达式,则会转换成方法再给 getter。
  • cb:当 getter 中引用到的 data 发生改变的时候,就会触发该回调。
  • options:额外参数,可以传入的参数为包括deepuserlazysync,这些值默认都是为 false。
    • deep 如果为 true,会对 getter 返回的对象再做一次深度遍历,进行进一步的依赖收集。
    • user 是用于标记这个监听是否由用户通过 $watch 调用的。
    • lazy 用于标记 watcher 是否为懒执行,该属性是给 computed data 用的,当 data 中的值更改的时候,不会立即计算 getter 获取新的数值,而是给该 watcher 标记为dirty,当该 computed data 被引用的时候才会执行从而返回新的 computed data,从而减少计算量。
    • sync 则是表示当 data 中的值更改的时候,watcher 是否同步更新数据,如果是 true,就会立即更新数值,否则在 nextTick 中更新。

了解了入参是用来干嘛的之后,也就基本上知道 Watcher 这个对象干了啥。

Dep

Dep 则是 vue 实现的一个处理依赖关系的对象,具体实现在 core/observer/dep.js 中,代码量相当少,很容易理解。

Dep 主要起到一个纽带的作用,就是连接 reactive data 与 watcher,每一个 reactive data 的创建,都会随着创建一个 dep 实例。参见 observer/index.js 中的defineReactive 方法,精简的 defineReactive 方法如下。

function defineReactive(obj, key, value) {
     
    const dep = new Dep();
    Object.defineProperty(obj, key, {
     
        get() {
     
          if (Dep.target) {
     
            dep.depend();
          }
          return value
        }
        set(newValue) {
     
            value = newValue;
            dep.notify()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值