javascript - 循环持续时 DOM 不会更新

标签 javascript dom vue.js

在困难周期之前分配的变量。 javascript 上的值已更改。但是 dom 端的值在循环结束时发生了变化。 无法显示加载分区。 如何在循环继续时显示加载的 div。

var vm = new Vue({
  el: '#app',
  data: {

    loading: false,

  },
  methods: {
    run() {

      this.loading = true;
      console.log(this.loading);
      for (let i = 0; i < 1000000000; i++) {}
      this.loading = false;
      console.log(this.loading);
    },
    runWithAsync() {
      vm.loading = true;
      console.log(this.loading);
      new Promise(function(resolve, reject) {
        for (let i = 0; i < 1000000000; i++) {}
        resolve(true);
      }).then((result) => {
        vm.loading = false;
        console.log(this.loading);
      })
    },
    runWithAsyncTimeout() {
      this.loading = true;
      console.log(this.loading);
      setTimeout(function() {
        new Promise(function(resolve, reject) {
          for (let i = 0; i < 1000000000; i++) {}
          resolve(true);
        }).then((result) => {
          this.loading = false;
          console.log(this.loading);
        })
      }.bind(this), 100)
    }
  }
})
.loading {
  width: 100%;
  height: 100vh;
  background: #ccc;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>
<div id="app">
  <button @click="run">run</button>
  <button @click="runWithAsync">runWithAsync</button>
  <button @click="runWithAsyncTimeout">runWithAsyncTimeout</button>
  <button @click="loading = !loading">change loading</button> {{ loading }}
  <div class="loading" v-if="loading"></div>
</div>

最佳答案

考虑了一会儿之后,我想出了一个 绝妙的 解决方案,其形式是 onRender 函数。

Vue 有一个异步更新机制,您可以在使用 Vue.nextTickvm.$nextTick ( View 模型实例函数)调整数据后等待。但这会在 DOM 已更改但尚未呈现后执行回调。如果您随后 requestAnimationFrame 您将在下一次渲染之前结束。此时请求另一个动画帧将导致代码运行到下一帧渲染之前,因此最终会发生渲染:

// This is dumb.
const onRender = callback =>
    Vue.nextTick(() =>
      requestAnimationFrame(() => 
        requestAnimationFrame(callback)));

var vm = new Vue({
  el: '#app',
  data: {

    loading: false,

  },
  methods: {
    run() {
      this.loading = true;
      console.log(this.loading);
      onRender(() => {
        for (let i = 0; i < 1000000000; i++) {}
        this.loading = false;
        console.log(this.loading);
      });
    }
  }
})
.loading {
  width: 100%;
  height: 100vh;
  background: #ccc;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>
<div id="app">
  <button @click="run">run</button>
  <button @click="loading = !loading">change loading</button> {{ loading }}
  <div class="loading" v-if="loading"></div>
</div>


使用异步支持:

// Look at them arrows!
const onRender = (callback = () => {}) =>
  new Promise(res =>
    Vue.nextTick(() =>
      requestAnimationFrame(() => 
        requestAnimationFrame(() => res(callback())))));

var vm = new Vue({
  el: '#app',
  data: {

    loading: false,

  },
  methods: {
    async run() {
      this.loading = true;
      console.log(this.loading);
      await onRender();
      for (let i = 0; i < 1000000000; i++) {}
      this.loading = false;
      console.log(this.loading);
    }
  }
})
.loading {
  width: 100%;
  height: 100vh;
  background: #ccc;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>
<div id="app">
  <button @click="run">run</button>
  <button @click="loading = !loading">change loading</button> {{ loading }}
  <div class="loading" v-if="loading"></div>
</div>

关于javascript - 循环持续时 DOM 不会更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49497612/

相关文章:

javascript - 使用纯 JavaScript 创建对此 HTML 元素的引用的最有效方法是什么?

php - 使用 PHP 或 Javascript 去掉最后一个逗号

javascript - jQuery DOM 数组作为参数

javascript - 默认选择剑道组合框

c# - 如何使用 sdocvw.dll 在 c# 中监听任何 DOM 事件

vue.js - 无法获得 textarea 的 scrollHeight 的正确值 - VueJs,Vuetify

javascript - 如何在 Vue.js 方法中使用外部 JavaScript 对象

javascript - 何时使用 Vuex 从数据库初始加载状态

javascript - 安装后 'react-navigation' 开发服务器返回响应码 :500

javascript - document.referrer 不返回完整的 url