iis服务器助手广告广告
返回顶部
首页 > 资讯 > 前端开发 > JavaScript >Vue数据变化后页面更新详细介绍
  • 665
分享到

Vue数据变化后页面更新详细介绍

Vue页面更新Vue数据变化后页面更新 2022-11-13 18:11:22 665人浏览 八月长安
摘要

首先会通过module.hot.accept监听文件变化,并传入该文件的渲染函数: module.hot.accept( "./App.Vue?vue&type=templa

首先会通过module.hot.accept监听文件变化,并传入该文件的渲染函数:

module.hot.accept( "./App.Vue?vue&type=template&id=472cff63&scoped=true&", __webpack_OUTDATED_DEPENDENCIES__ => {  _App_vue_vue_type_template_id_472cff63_scoped_true___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__( "./App.vue?vue&type=template&id=472cff63&scoped=true&");
(function () {
      api.rerender('472cff63', {
        render: _App_vue_vue_type_template_id_472cff63_scoped_true___WEBPACK_IMPORTED_MODULE_0__.render,
        staticRenderFns: _App_vue_vue_type_template_id_472cff63_scoped_true___WEBPACK_IMPORTED_MODULE_0__.staticRenderFns
      })
    })(__WEBPACK_OUTDATED_DEPENDENCIES__); })

随后执行rerender方法,只贴重点部分代码:

 record.Ctor.options.render = options.render
    record.Ctor.options.staticRenderFns = options.staticRenderFns
    record.instances.slice().forEach(function (instance) {
      instance.$options.render = options.render
      instance.$options.staticRenderFns = options.staticRenderFns
      // reset static trees
      // pre 2.5, all static trees are cached together on the instance
      if (instance._staticTrees) {
        instance._staticTrees = []
      }
      // 2.5.0
      if (Array.isArray(record.Ctor.options.cached)) {
        record.Ctor.options.cached = []
      }
      // 2.5.3
      if (Array.isArray(instance.$options.cached)) {
        instance.$options.cached = []
      }
      // post 2.5.4: v-once trees are cached on instance._staticTrees.
      // Pure static trees are cached on the staticRenderFns array
      // (both already reset above)
      // 2.6: temporarily mark rendered scoped slots as unstable so that
      // child components can be forced to update
      var restore = patchScopedSlots(instance)
      instance.$forceUpdate()
      instance.$nextTick(restore)
    })

首先会给当前的VueComponent的Options和实例里面的渲染函数替换为最新,然后执行实例上的forceUpdate方法:

Vue.prototype.$forceUpdate = function () {
          var vm = this;
          if (vm._watcher) {
              vm._watcher.update();
          }
      };

该方法是执行watcher实例的update方法:

Watcher.prototype.update = function () {
          
          if (this.lazy) {
              this.dirty = true;
          }
          else if (this.sync) {
              this.run();
          }
          else {
              queueWatcher(this);
          }
      };
function queueWatcher(watcher) {
      var id = watcher.id;
      if (has[id] != null) {
          return;
      }
      if (watcher === Dep.target && watcher.noRecurse) {
          return;
      }
      has[id] = true;
      if (!flushing) {
          queue.push(watcher);
      }
      else {
          // if already flushing, splice the watcher based on its id
          // if already past its id, it will be run next immediately.
          var i = queue.length - 1;
          while (i > index$1 && queue[i].id > watcher.id) {
              i--;
          }
          queue.splice(i + 1, 0, watcher);
      }
      // queue the flush
      if (!waiting) {
          waiting = true;
          if (!config.async) {
              flushSchedulerQueue();
              return;
          }
          nextTick(flushSchedulerQueue);
      }
  }

重点看 queueWatcher(this),将最新的watcher放入quene队列并且将flushSchedulerQueue函数传给nextTick。

function nextTick(cb, ctx) {
      var _resolve;
      callbacks.push(function () {
          if (cb) {
              try {
                  cb.call(ctx);
              }
              catch (e) {
                  handleError(e, ctx, 'nextTick');
              }
          }
          else if (_resolve) {
              _resolve(ctx);
          }
      });
      if (!pending) {
          pending = true;
          timerFunc();
      }
      // $flow-disable-line
      if (!cb && typeof Promise !== 'undefined') {
          return new Promise(function (resolve) {
              _resolve = resolve;
          });
      }
  }

在callbacks里面放入一个执行回调的函数。并执行timerFunc():

timerFunc = function () {
          p_1.then(flushCallbacks);
          // In problematic UIWebViews, Promise.then doesn't completely break, but
          // it can get stuck in a weird state where callbacks are pushed into the
          // microtask queue but the queue isn't being flushed, until the browser
          // needs to do some other work, e.g. handle a timer. Therefore we can
          // "force" the microtask queue to be flushed by adding an empty timer.
          if (isiOS)
              setTimeout(noop);
      };

该方法异步执行flushCallbacks:

function flushCallbacks() {
      pending = false;
      var copies = callbacks.slice(0);
      callbacks.length = 0;
      for (var i = 0; i < copies.length; i++) {
          copies[i]();
      }
  }

开始执行回调函数我们第一次放进去的函数flushSchedulerQueue:

function flushSchedulerQueue() {
      currentFlushTimestamp = getNow();
      flushing = true;
      var watcher, id;
      // Sort queue before flush.
      // This ensures that:
      // 1. Components are updated from parent to child. (because parent is always
      //    created before the child)
      // 2. A component's user watchers are run before its render watcher (because
      //    user watchers are created before the render watcher)
      // 3. If a component is destroyed during a parent component's watcher run,
      //    its watchers can be skipped.
      queue.sort(sortCompareFn);
      // do not cache length because more watchers might be pushed
      // as we run existing watchers
      for (index$1 = 0; index$1 < queue.length; index$1++) {
          watcher = queue[index$1];
          if (watcher.before) {
              watcher.before();
          }
          id = watcher.id;
          has[id] = null;
          watcher.run();
          // in dev build, check and stop circular updates.
          if (has[id] != null) {
              circular[id] = (circular[id] || 0) + 1;
              if (circular[id] > MAX_UPDATE_COUNT) {
                  warn$2('You may have an infinite update loop ' +
                      (watcher.user
                          ? "in watcher with expression \"".concat(watcher.expression, "\"")
                          : "in a component render function."), watcher.vm);
                  break;
              }
          }
      }
      // keep copies of post queues before resetting state
      var activatedQueue = activatedChildren.slice();
      var updatedQueue = queue.slice();
      resetSchedulerState();
      // call component updated and activated hooks
      callActivatedHooks(activatedQueue);
      callUpdatedHooks(updatedQueue);
      // devtool hook
      
      if (devtools && config.devtools) {
          devtools.emit('flush');
      }
  }

首先触发watcher.before(),该方法是beforeUpdate的hook。然后执行watcher.run()方法:

Watcher.prototype.run = function () {
          if (this.active) {
              var value = this.get();
              if (value !== this.value ||
                  // Deep watchers and watchers on Object/Arrays should fire even
                  // when the value is the same, because the value may
                  // have mutated.
                  isObject(value) ||
                  this.deep) {
                  // set new value
                  var oldValue = this.value;
                  this.value = value;
                  if (this.user) {
                      var info = "callback for watcher \"".concat(this.expression, "\"");
                      invokeWithErrorHandling(this.cb, this.vm, [value, oldValue], this.vm, info);
                  }
                  else {
                      this.cb.call(this.vm, value, oldValue);
                  }
              }
          }
      };

该方法watcher.get方法,该方法会重新执行render方法生成vnode,然后调用update方法更新节点:

updateComponent = function () {
              vm._update(vm._render(), hydrating);
          };

总结

1.获取监听文件最新的render和staticRenderFns并赋值给当前的VueComponent和当前vm实例。

2.使用$forceUpdate添加当前的vm的watcher并在queue中,最后异步执行flushSchedulerQueue,该函数遍历quene执行watcher的run方法,该方法会执行vm实例的_update方法完成更新。

到此这篇关于Vue数据变化后页面更新详细介绍的文章就介绍到这了,更多相关Vue页面更新内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Vue数据变化后页面更新详细介绍

本文链接: https://www.lsjlt.com/news/169878.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Vue数据变化后页面更新详细介绍
    首先会通过module.hot.accept监听文件变化,并传入该文件的渲染函数: module.hot.accept( "./App.vuevue&type=templat...
    99+
    2022-11-13
    Vue页面更新 Vue数据变化后页面更新
  • vue数据变化但页面刷新问题
    目录vue数据变化但页面刷新watch监听到数据的变化但页面没有刷新没有监听到数据的变化改变了数据却没有自动刷新说下结论vue数据变化但页面刷新 watch监听到数据的变化但页面没有...
    99+
    2022-11-13
  • 详解vue表格更新页面怎么同步数据
    Vue是一种流行的JavaScript框架,已被广泛应用于前端开发中。在开发过程中,我们通常需要使用表格来展示数据。当数据发生更新时,我们希望页面能够同步更新,以保证用户体验。那么在Vue中,表格如何实现数据的同步更新呢?一、Vue的响应式...
    99+
    2023-05-14
  • vue数据变化但页面刷新问题怎么解决
    今天小编给大家分享一下vue数据变化但页面刷新问题怎么解决的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。vue数据变化但页面...
    99+
    2023-06-30
  • vue列表数据删除后主动刷新页面及刷新方法详解
    问题描述: 前端删除一条数据或者新增数据后,后端操作成功,但前端不会自动刷新,需要重新刷新当前页面 (用vue-router重新路由到当前页面,页面是不进行刷新的 ,采用windo...
    99+
    2022-11-12
  • 如何解决vue路由变化页面数据不刷新的问题
    这篇文章给大家分享的是有关如何解决vue路由变化页面数据不刷新的问题的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。每天记录一点点,把我遇到的问题记录下来, 希望可以帮助到更多和我...
    99+
    2022-10-19
  • 如何解决IE11 vue+webpack项目中数据更新后页面没有刷新的问题
    这篇文章主要介绍如何解决IE11 vue+webpack项目中数据更新后页面没有刷新的问题,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!vue +webpack 项目中数据更新后页面...
    99+
    2022-10-19
  • vue面试created中两次数据修改会触发几次页面更新详解
    目录面试题:一、同步的二、异步的三、附加总结面试题: created生命周期中两次修改数据,会触发几次页面更新? 一、同步的 先举个简单的同步的例子: new Vue({ el...
    99+
    2022-12-22
    vue created数据修改页面更新 vue created
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作