vue dom更新,vue 异步更新

  vue dom更新,vue 异步更新

  Vue中的数据更新是异步的,这意味着我们无法在修改数据后立即获得修改后的DOM元素。本文介绍了vue异步更新dom的实现,有兴趣的朋友可以参考一下。

  

目录

   VUE异步更新DOM的原理1什么时候可以得到真正的DOM元素?2为什么Vue需要nextTick方法来获取最新的DOM?3为什么会这样。$nextTick能够获得更新的DOM吗?总结:vue异步更新数据对象的原理:vue中数据方法返回的对象;

  Dep对象:每个数据属性将创建一个Dep来收集所有使用该数据的观察器对象;

  Watcher对象:主要用于渲染DOM

  

Vue异步更新DOM的原理

  Vue中的数据更新是异步的,这意味着我们无法在修改数据后立即获得修改后的DOM元素。

  

1 什么时候能获取到真正的DOM元素?

  在Vue的nextTick回调中。

  

2 为什么Vue需要通过nextTick方法才能获取最新的DOM?

  2.1 When调用Watcher更新视图时,不会直接更新,而是将Watcher添加到队列中,然后将具体的更新方法flushSchedulerQueue传递给nexTick进行调用。

  //src核心观察者watcher . js scheduler.js//在更新一个数据时会依次执行下面的代码。

  //1.触发数据集

  //2.呼叫dep.notify

  //3.Dep将遍历所有相关的观察器来执行更新方法。

  类监视器{

  //4.执行更新操作。

  update() {

  queueWatcher(这个);

  }

  }

  常量队列=[];

  函数queueWatcher(watcher: Watcher) {

  //5.将当前观察器添加到异步队列中。

  queue . push(watcher);

  //6.执行异步队列并传入回调。

  next tick(flushSchedulerQueue);

  }

  //更新视图的具体方法

  函数flushSchedulerQueue() {

  让观察者,id;

  //排序,先渲染父节点,再渲染子节点。

  //这样可以避免不必要的子节点渲染,比如父节点中带有false v-if的子节点,就不需要渲染了。

  queue.sort((a,b)=a . id-b . id);

  //遍历所有观察器进行批量更新。

  for(索引=0;索引队列长度;索引){

  watcher=queue[index];

  //更新DOM

  watcher . run();

  }

  }

  2.2 nextTick -将传递的flushSchedulerQueue添加到回调数组中,然后执行timerFunc方法。

  const回调=[];

  让timerFunc

  函数nextTick(cb?函数,ctx?对象){

  let _ resolve

  //1.将传入的flushSchedulerQueue方法添加到回调数组。

  callbacks.push(()={

  CB . call(CTX);

  });

  //2.执行异步任务

  //这个方法会根据浏览器兼容性选择不同的异步策略。

  timer func();

  }

  2.3 timerFunc方法——它是根据浏览器兼容性创建的异步方法。执行此方法后,将为特定的DOM更新调用flushSchedulerQueue方法。

  让timerFunc

  //确定是否与承诺兼容

  如果(类型的承诺!==未定义){

  timerFunc=()={

  Promise.resolve()。然后(flush callbacks);

  };

  //确定它是否与MutationObserver兼容

  //https://developer . Mozilla . org/zh-CN/docs/Web/API/mutation observer

  } else if (typeof MutationObserver!==未定义){

  设计数器=1;

  const observer=new mutation observer(flush callbacks);

  const textNode=document . create textNode(String(counter));

  observer.observe(textNode,{

  characterData:真的,

  });

  timerFunc=()={

  计数器=(计数器1)% 2;

  text node . data=String(counter);

  };

  //确定是否与setImmediate兼容。

  //这个方法存在于一些IE浏览器中

  } else if (typeof setImmediate!==未定义){

  //这是一个宏任务,但比setTimeout要好

  timerFunc=()={

  set immediate(flush callbacks);

  };

  }否则{

  //如果以上方法都不知道,则使用setTimeout 0

  timerFunc=()={

  setTimeout(flushCallbacks,0);

  };

  }

  //异步执行结束后,执行所有回调方法,即执行flushSchedulerQueue。

  函数flushCallbacks() {

  for(设I=0;一份,长度;i ) {

  回调[I]();

  }

  }

  2.4提高逻辑判断能力

  2.4.1判断has标识,避免添加相同的观察者;排队;

  2.4.2判断等待标志,让所有守望者一个滴答更新;

  2.4.3判断flushing logo,处理观察器渲染时可能产生的新观察器。

  如果v-if条件被触发,则添加新的观察器渲染。

  提示:nextTick只是由Promise、setTimeout等方法简单模拟的异步任务。

  

3 为什么this.$nextTick 能够获取更新后的DOM?

  称之为。$nextTick实际上是调用图中的nextTick方法来执行异步队列中的回调函数。根据先入先出原则,修改数据触发的更新异步队列会先执行,执行后会生成一个新的DOM。然后当这个回调函数。$nextTick,就可以获得更新后的DOM元素。

  //当我们使用这个的时候。$nextTick,我们实际上调用的是nextTick方法。

  vue . prototype . $ next tick=Function(fn:Function){

  返回nextTick(fn,this);

  };

  

总结:vue异步更新的原理

  修改Vue中的数据将触发与该数据相关的所有观察器进行更新。首先,所有的观察者将被添加到队列中。然后,调用nextTick方法来执行异步任务。在异步任务的回调中,对队列中的Watcher进行排序,然后执行相应的DOM更新。

  关于vue异步更新dom的实现,本文到此结束。关于vue异步更新dom的更多信息,请搜索我们之前的文章或者继续浏览下面的相关文章。希望大家以后能多多支持我们!

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

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