vue2.0响应式原理,vue 响应式

  vue2.0响应式原理,vue 响应式

  本文主要介绍Vue2响应系统,主要实现一个依赖于数据的功能。当相关数据发生变化时,必须重新执行该功能。有关下面的更多信息,请参考所需的合作伙伴。

  :

目录

   1.响应系统应该做什么。响应数据3。保存当前执行的功能4。响应数据5。观察者对象6。测试7。总结前言:

  目前,工作中可能有一些需求正在使用技术堆栈。知道是什么就知道为什么更重要。为了更好地使用它,更快地解决问题,我最近学习了一些与源代码相关的知识。虽然网上的总结很多,很多都有自己的,但是自己的不多。欢迎大家一起讨论学习,发现问题请指出。40%Vue2VueVue

  

一、响应式系统要干什么

  回到最简单的代码:

  数据={

  文本:“你好,世界”

  }

  const updateComponent=()={

  Console.log (received ,data . text);

  }

  更新组件()

  data.text=你好,梁

  //运行结果

  //收到hello,world

  一个响应系统需要做什么:一个依赖于数据的功能。当相关数据发生变化时,需要重新执行该函数。数据数据

  我们期望的效果:修改上述内容后,再次执行该功能。data.textupdateComponent

  为了实现响应式系统,我们需要做两件事情:

  当您知道哪些函数依赖于datadata中的数据时,调用依赖于它的函数。为了实现点,我们需要在执行函数时保存当前函数,然后将函数保存到读取数据处的当前数据。一个

  第一点解决了。当修改数据时,保存的功能可以执行一次。2

  在读取数据修改数据中,我们需要做一些额外的事情。我们可以重写对象属性的sum函数。Object.defineProperty()getset

  

二、响应式数据

  让我们编写一个覆盖属性求和函数的函数。装置

  /**

  *定义对象的反应属性。

  */

  导出函数defineReactive(obj,key,val) {

  const property=object . getownpropertydescriptor(obj,key);

  //读取用户可能自己定义的get,set。

  const getter=property property . get;

  const setter=property property . set;

  //val没有用于手动分配的来电

  如果((!getter setter)arguments . length===2){

  val=obj[key];

  }

  Object.defineProperty(obj,key,{

  可枚举:真,

  可配置:真,

  get:函数reactiveGetter() {

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

  /*********************************************/

  //1.这里你需要保存当前正在执行的函数。

  /*********************************************/

  返回值;

  },

  set:函数reactiveSetter(newVal) {

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

  if (setter) {

  setter.call(obj,new val);

  }否则{

  val=newVal

  }

  /*********************************************/

  //2.将执行依赖于当前数据相关性的函数。

  /*********************************************/

  },

  });

  }

  为了调用方便,我们将step和step中的操作封装成一个类。12Dep

  导出默认类Dep {

  静态目标;//当前正在执行的函数

  潜艇;//依赖函数

  构造函数(){

  this . subs=[];//保存所有需要执行的功能

  }

  addSub(sub) {

  this . subs . push(sub);

  }

  依赖(){

  //触发get时转到此处

  if (Dep.target) {

  //委托Dep.target调用addSub

  dep . target . add dep(this);

  }

  }

  通知(){

  for(设i=0,l=this . subs . length;I l;i ) {

  this.subs[i]。update();

  }

  }

  }

  Dep.target=null//静态变量,全局唯一

  我们将当前执行的函数保存到类的变量中。Deptarget

  

三、保存当前正在执行的函数

  为了保存当前函数,我们还需要写一个类,传入要执行的函数,保存在类的属性中,然后交给类执行。WatcherWatchergetterWatcher

  这样,在类中,不是保存当前函数,而是保存当前函数的对象。DepsubsWatcher

  从导入Dep。/dep ;

  导出默认类观察器{

  构造函数(Fn) {

  this.getter=Fn

  this . get();

  }

  /**

  *评估getter,并重新收集依赖项。

  */

  get() {

  Dep.target=this//保存包装当前正在执行的函数的观察器。

  让价值;

  尝试{

  //调用当前传入函数触发对象属性的get

  value=this . getter . call();

  } catch (e) {

  扔e;

  }

  返回值;

  }

  /**

  *向此指令添加依赖项。

  */

  addDep(dep) {

  //在触发get之后,您将转到这里并收集当前的依赖项

  //当前正在执行的函数的监视器被保存到dep中的subs中

  dep . addsub(this);

  }

  /**

  *用户界面。

  *当依赖关系改变时将被调用。

  */

  //修改对象属性值时触发set。去这里。

  update() {

  this . run();

  }

  /**

  *调度程序作业界面。

  *将由调度程序调用。

  */

  run() {

  this . get();

  }

  }

  Watcher的作用是把正在执行的函数包装起来保存进去,然后调用传入的函数。此时,触发object属性的函数将收集当前的。WatcherDep.targetgetWatcher

  如果将来修改了object属性的值,就会触发object属性,然后调用之前收集的对象,通过object的方法调用最初执行的函数。setWatcherWatcheruptate

  

四、响应式数据

  让我们回到之前没有完成的函数。按照上面的思路,我们来完成吧。定义活动

  从导入Dep。/dep ;

  /**

  *定义对象的反应属性。

  */

  导出函数defineReactive(obj,key,val) {

  const property=object . getownpropertydescriptor(obj,key);

  //读取用户可能自己定义的get,set。

  const getter=property property . get;

  const setter=property property . set;

  //val没有用于手动分配的来电

  如果((!getter setter)arguments . length===2){

  val=obj[key];

  }

  /*********************************************/

  const Dep=new Dep();//保存一个Dep对象来保存依赖于该变量所有观察器

  /*********************************************/

  Object.defineProperty(obj,key,{

  可枚举:真,

  可配置:真,

  get:函数reactiveGetter() {

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

  /*********************************************/

  //1.这里你需要保存当前正在执行的函数。

  if (Dep.target) {

  dep . depend();

  }

  /*********************************************/

  返回值;

  },

  set:函数reactiveSetter(newVal) {

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

  if (setter) {

  setter.call(obj,new val);

  }否则{

  val=newVal

  }

  /*********************************************/

  //2.将执行依赖于当前数据相关性的函数。

  dep . notify();

  /*********************************************/

  },

  });

  }

  

五、Observer 对象

  让我们再写一个方法,让对象的所有属性都有响应。观察者

  导出类观察者{

  构造函数(值){

  this.walk(值);

  }

  /**

  *遍历对象的所有属性,并调用defineReactive。

  *拦截对象属性的get和set方法。

  */

  步行

  const keys=object . keys(obj);

  for(设I=0;i keys.lengthi ) {

  defineReactive(obj,keys[I]);

  }

  }

  }

  我们提供了一个负责创建对象的方法。观察者

  导出函数观察(值){

  设ob=新观察者(值);

  返回ob;

  }

  

六、测试

  将上边的方法引入到文章最开头的例子,来执行一下:

  从导入{ observe }。/reactive ;

  从导入观察器。/watcher ;

  常量数据={

  文字:“你好,世界”,

  };

  //使数据具有响应性

  观察(数据);

  const updateComponent=()={

  Console.log (received ,data . text);

  };

  //当前函数由Watcher执行

  新观察器(update component);

  data.text=你好,梁;

  这时候就会输出两次~

  收到,你好,世界

  收到,喂,梁

  这表明我们的响应系统是成功的。

  

七、总结

  先从整体理解了响应式系统的整个流程:

  每个属性都有一个数组,用来保存当前执行的函数。当属性被读取时,它将被触发,当前值将被保存在数组中。当属性值被修改时,先前保存的函数将通过数组中的对象执行。subwatchergetwatchers sub watcher

  关于Vue2响应式系统介绍的这篇文章到此为止。有关Vue2响应式系统的更多信息,请搜索我们以前的文章或继续浏览下面的相关文章。希望大家以后能多多支持我们!

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

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