vue响应式源码解析,vue.js响应式原理

  vue响应式源码解析,vue.js响应式原理

  最近去面试的人都会有这种体验。去年面试官只问我怎么用vue。今年开始问vue的响应式原理。本文将详细介绍。

  :

目录

   1.Vue.js函数:2。Observer.js函数(数据劫持):3。Compiler.js函数:4。Dep.js函数:5。Watcher.js函数:整体分析Vue的基本结构如下图所示:(注:https://github.com/1512955040/MiniVue完整代码github地址)

  在上图中,我们模拟了最小vue的整体结构。首先,我们创建一个vue类型,它负责将数据中的成员注入到vue实例中,并将它们转换成getter/setter。观察器的作用是劫持数据,监视数据中的属性,如果数据发生变化,就获取最新的值,并通知dep。编译器的作用是解析每个元素中的指令和差分表达式,并用相应的数据替换它们。Dep的作用是添加观察器,并在数据发生变化时通知所有观察器。Watcher中有一个更新方法来更新视图。我们用代码一个一个实现吧。

  

1.Vue.js功能:

  1-1负责接收初始化参数(选项)

  1-2负责将数据中的属性注入到vue实例中,并将其转换为getter/setter。

  1-3负责调用observer来监控数据中所有属性的变化。

  1-4负责调用编译器解析指令/差异表达式。

  类图结构如下:

  如上图,vue类中有三个属性,分别是$ options、$ el和$ data。这三个属性记录从构造函数传递的参数。_proxyData是vue类中的一个方法。

  因此,以_开头的成员是私有成员。这个方法的作用是将数据中的属性转换成getter和setter,并注入到vue实例中。

  Vue类{

  构造函数(选项){

  //1.通过属性保存选项中的数据。

  这个。$options=options {}

  这个。$data=options.data {}

  这个。$el=typeof options.el===string ?document . query selector(options . El):options . El

  //2.将数据中的成员转换成getter和setter,并注入vue实例。

  这个。_proxyData(this。$data)

  //3.调用observer对象来监视数据的变化。

  新观察家(这个。$data)

  //4.调用编译器对象来解析指令和差异表达式。

  新编译器(this)

  }

  //将Vue的属性转换成getter和setter,注入到Vue实例中

  _proxyData(data){

  //遍历数据中的所有属性

  Object.keys(数据)。forEach(key={

  //将数据的属性注入vue实例的全局

  Object.defineProperty(this,key,{

  可枚举:真,

  可配置:真,

  get(){

  返回数据[键]

  },

  set(newValue){

  if(newValue===data[key]){

  返回

  }

  数据[键]=新值

  }

  })

  })

  }

  }

  

2.Observer.js功能(数据劫持):

  2-1负责将数据选项中的属性转换成响应数据。

  2-2数据中的一个属性也是一个对象,这个属性转换成响应数据。

  2-3发送数据更改通知

  类图结构如下:

  如上图所示:

  walk方法的作用是遍历数据中的所有属性,defineReactive方法是定义响应数据,即通过调用defineReactive方法将属性转换为getter和setter。

  课堂观察者{

  构造函数(数据){

  this.walk(数据)

  }

  //walk方法//遍历数据中的所有属性

  行走(数据){

  //1.确定数据是否是对象。

  如果(!数据数据类型!==object){

  返回

  }

  //2.遍历数据对象的所有属性

  Object.keys(数据)。forEach(key={

  this.defineReactive(data,key,data[key])

  })

  }

  ///degineReactivce方法定义响应数据,并将属性转换为getter和setter。

  defineReactive(obj,key,val) {

  让那个=这个

  //负责收集依赖项和发送通知

  let dep=new Dep()

  //如果将val传递到对象中,还要将getter和setter方法添加到对象内部的属性中。

  这条路(瓦尔)

  Object.defineProperty(obj,key,{

  可枚举:真,

  可配置:真,

  get(){

  //收集依赖项

  dep . target dep . add sub(dep . target)

  返回值

  },

  set(newValue){

  if(newValue==val){

  返回

  }

  val=新值

  //如果将属性重新分配给对象,请将getter和setter方法添加到对象内部的属性中。

  //比如:vm.msg=Hello World 历史数据修改后,vm.msg={a:Hwllo World}

  //再次调用此方法将getter和setter方法添加到vm.msg.a中

  that.walk(新价值)

  //发送通知

  dep.notify()

  }

  })

  }

  }

  

3.Compiler.js功能:

  3-1负责编译模板,解析指令/差异表达式。

  3-2负责页面的第一次呈现

  3-3当数据改变时重新渲染视图。

  类图结构如下:

  如上图所示:

  Options.el,el构造函数传递的vm,vm是vue的一个实例,以下都是VM操作DOM的方法。编译方法在内部遍历dom对象的所有节点,并且

  判断这些节点是文本节点。如果是解析差异表达式的文本节点,如果是元素节点解析指令,isTextNode和isElementNode方法判断是否是文本节点。

  是元素节点。CompileElement和compileText方法解析不同的表达式和指令。IsDirective此方法确定元素属性是否是指令。

  

4.Dep.js功能:

  4-1收集依赖项并添加观察器。

  4-2通知所有观察员

  如上图所示:

  在vue的响应机制中,观察者模式用于响应数据的变化。Dep的作用是收集依赖,在getter方法中收集依赖,在setter方法中通知依赖。每一

  一个响应属性将创建一个Dep对象,该对象负责收集依赖于该属性的所有位置。所有依赖于该属性的位置都将创建一个观察器对象,所以

  Dep是在此属性中收集的观察器对象。setter方法用于通知依赖关系。当属性改变时,调用nodify方法发送通知,然后调用watcher对象。

  的更新方法。

  该类的组织如下:

  如上图所示:

  Subs是一个在dep中存储所有观察器的数组。addsub方法添加观察器,而watcher,notify方法发布通知。

  类Dep

  构造函数(){

  //存储所有观察器

  this.subs=[]

  }

  //添加观察者

  addSub(sub){

  if(子子更新){

  这个. subs.push(子)

  }

  }

  //发送通知

  通知(){

  this.subs.forEach(sub={

  子更新()

  })

  }

  }

  

5.Watcher.js功能:

  5-1当数据更改触发依赖关系时,dep通知所有观察器实例更新视图。

  5-2实例化自己时将自己添加到dep对象。

  如上图所示:

  数据中的每个属性都应该创建一个Dep对象。在收集依赖关系时,所有对象的观察器都被添加到dep对象的subs数组中,并发送给setter对象。

  知道,调用Dep对象的notify方法通知所有相关的watcher对象更新视图。

  类图结构如下:

  如上图所示:

  对象更新视图,cb回调函数,指示如何更新视图。更新视图时,需要一个属性键(数据中的属性名),oldvalue是key的对应值。

  类监视器{

  构造函数(vm,key,cb) {

  this.vm=vm

  //数据中的属性名

  this.key=key

  //回调函数负责更新视图

  this.cb=cb

  //将watcher对象记录到Dep类的静态属性target

  Dep.target=这

  //触发get方法,其中将调用addSub

  this.oldValue=vm[key]

  Dep.target=null

  }

  //当数据更改时更新视图

  update(){

  设newValue=this.vm[this.key]

  if(this.oldValue===newValue){

  返回

  }

  this.cb(新值)

  }

  }

  通过下图对整个过程做一个总结:

  以上就是本文关于Vue模拟响应式原理底层代码实现的例子。关于Vue响应式原理的更多信息,请搜索我们以前的文章或继续浏览下面的相关文章。希望大家以后能多多支持我们!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: