图解Vue核心

本文深入探讨Vue的核心机制,包括Object.defineProperty用于数据劫持,发布订阅模式实现数据变更通知,以及Vue实例、Observer、Compiler、Proxy和Watcher类的角色与交互。通过创建Vue实例的过程,详细阐述了数据绑定与视图更新的流程,揭示了一个简化的Vue工作原理。
摘要由CSDN通过智能技术生成

核心

本章节主要致力于Vue的核心实现

图解Vue核心

Vue的核心是Object.defineProperty+发布订阅模式。利用defineProperty劫持数据层的数据。当视图层用到数据层的数据时,利用发布订阅模式,在代理中添加一对多的依赖,视图层的多个模块依赖于一个数据层中的数据;当数据层的数据发生变化时,再次利用defineProperty劫持数据,通知所有依赖于该数据的视图层模块进行视图更新。

首先,我们先对Vue进行拆解,Vue可以分为以下几个类:

  1. Vue类:入口,主要负责初始化各个实例以及做一些代理任务,例如代理vue.data.msg为vue.msg
  2. Observer类:主要负责数据层的data中各个属性的数据劫持,创建与各个属性绑定的代理Proxy实例。在get中添加依赖与数据层中数据的视图模块(Watcher),在set中通知依赖于数据层中对应数据的视图层更新视图
  3. Compiler类:负责节点上的指令,内部利用Watcher建立视图层与数据层连接,最后渲染视图
  4. Proxy类:主要负责视图层与数据层的依赖订阅,以及数据层修改通知视图层更新,即发布订阅模式中的中间代理。
  5. Watcher类:主要负责获取对应视图层在数据层中的数据,从而建立视图层与数据层的连接

创建一个Vue实例会经过以下几个过程:

  1. 调用构造函数进行初始化
  2. 在构造函数中实例化Observer,为数据层中的data中的属性绑定defineProperty
  3. 在构造函数中实例化Compiler,解析标签中的指令,并且渲染视图

现在我们对过程2进行分解后,会经历以下几个过程:

  • 为数据层中所有data中的属性绑定defineProperty
  • 创建一个代理Proxy实例,用于管理订阅与发布
  • 在defineProperty内部调用get(订阅subscribe)时,为数据层data中的属性绑定对应于视图的Watcher
  • 在defineProperty内部调用set(发布publish)时,通知该属性下的proxy实例通知所有Watcher重新渲染视图

现在我们对过程3进行分解后,会经历以下几个过程:

  • 分析指令的类型做出不同使用不同方法编译节点
  • 为节点添加Watcher
  • Watcher将与数据层的data绑定,即做到了数据层与视图层绑定
  • Watcher将从数据层获取的数据返回给Compiler,Compiler最后在负责渲染视图,实现了真正的数据与视图绑定

以下是整体的流程图:

image-20210311151654602

image-20210311151730576

以下是调用数据层中get的结果:
Proxy负责添加负责提供视图更新数据的Watcher,建立依赖,让Watcher与数据层绑定

image-20210311151418252

以下是调用数据层中set的结果:
Proxy负责通知负责提供视图更新数据的Watcher,让Watcher重新从数据层获取数据,然后让Compiler渲染视图

image-20210311151434303

代码👈

// 为Vue实例中data中的属性定义defineProperty
class Observer {

}
// 编译vue文件中的节点上的指令与Vue实例中的data建立连接
class Compiler {
  constructor() {
    let node = this.compiler();
    parent.appendChild(node);
  }
  compiler() {

  }
}
class Watcher {  
}
// 发布订阅模式中的代理,用于管理添加依赖与通知
class Proxy {
  constructor() {
    this.map = {};
  }
  subscribe() {

  }
  notify() {

  }
}
class Vue {
  constructor(options) {
    this.$data = options.data || {};
    this._proxyData(this.$data);
  }
  /* 
    使用Object.defineProperty来管理当Vue中的data
   */
  _proxyData(data) {
    
  }
}

至此,一个极简的Vue实现了,其中还存在许多问题,例如data应该使用函数等等。更多内容将后续更新~🐞

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值