VueJS не рендерится до завершения цикла - PullRequest
0 голосов
/ 13 апреля 2019

У меня есть этот фрагмент кода VueJS:

new Vue({
  el: '#app',
  data: {
    tiles: [
      { isActive: false },
      { isActive: false },
      { isActive: false },
      { isActive: false },
      { isActive: false }
    ]

  },
  methods: {
    startWithLoop: function() {
      console.log("startWithLoop");
      for(var i = 0; i < 10000; i++ ) { this.blink() };
    },
    startWithInterval: function() {
      console.log("startWithInteral");
      setInterval(this.blink);
    },
    blink: function(){
      console.log("blink");
      var index = Math.floor(Math.random() * this.tiles.length);
      this.tiles[index].isActive = !this.tiles[index].isActive;
    }
  }
})

Если я вызываю метод startWithInterval, я могу видеть в представлении, как tiles постоянно изменяет состояние.

Если я вызываю метод startWithLoop, я не вижу никаких изменений в представлении, пока цикл не закончится.

Вот JSFiddle

Как можноЯ запускаю изменения в представлении на каждом шаге цикла?

Ответы [ 3 ]

2 голосов
/ 13 апреля 2019

Нет, это то, как Javascript eventloop работает в браузерах (и не только).

Вы можете представить, что Javascript выполняется только в «промежутках между моментами», так что ваша картина того, что происходит в браузереэто моментальный снимок.

0 голосов
/ 20 апреля 2019

Подводя итог и объединяя все предложения, я понял, что:

  • В середине цикла JS VueJS не собирается ничего рендерить

Таким образом, вы должны перенести итерации вашего цикла в другой процесс.Я думал, что обещания могут быть решением, но проще использовать setTimeout() без delay param.

Так что вместо этого:

for(var i = 0; i < 10000; i++ ) { 
  this.blink() 
};

Мой код будет выглядеть так:

for(var i = 0; i < 10000; i++ ) { 
  setTimeout(this.blink)
}
0 голосов
/ 13 апреля 2019

Вы можете написать что-то похожее на цикл, которое использует setTimeout, чтобы позволить Vue заметить изменения, а затем отправить их в DOM.

beforeDestroy() {
  if (this.timeout != null) {
    clearTimeout(this.timeout);
    this.timeout = null;
  }
},
startWithLoop: function() {
  console.log("startWithLoop");
  let i = 0
  const iter = () => {
    this.blink();
    i += 1;
    if (i < 10000) {
      this.timeout = setTimeout(iter);
    }
  }
  iter();
},

Рабочая скрипка с изменениями сверху: https://jsfiddle.net/ssorallen/9pqscat1/3/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...