Как заставить Vue обновить актуальный DOM сразу, когда nextTick не работает, из файла .vue? - PullRequest
0 голосов
/ 07 декабря 2018

Когда у меня есть компонент Vue в файле .vue с элементом данных isLoading: false и шаблоном:

<div v-show="isLoading" id="hey" ref="hey">Loading...</div>
<button @click="loadIt()">Load it</button>

И методом:

loadIt() {
  this.isLoading = true
  this.$nextTick(() => {
    console.log(this.$refs.hey)                  // virtual DOM
    console.log(document.getElementById('hey'))  // actual DOM
    // ...other work here
  })
}

Я подумалчто функция nextTick позволит обновлять как виртуальный, так и реальный DOM, и, таким образом, две строки console.log будут выводить одинаковые результаты.Однако они этого не делают: кажется, что реальный DOM не обновляется сразу, и, следовательно, второй журнал приводит к элементу с display: none;, тогда как первый журнал нет - я получаю это на консоли:

<div id="hey" data-v-964d645e="" style="">
<div id="hey" data-v-964d645e="" style="display: none;">

(Кстати, даже если я использую setTimeout вместо this.$nextTick, я получаю те же результаты из console.log. Я также пытался использовать хук updated, но тот жесимптомы возникают там. Если я кодирую любой вариант в файле .js, проблема исчезает, но сохраняется в файле .vue.)

Есть ли какая-то оптимизация или дальнейшая асинхронность в обновлении Vueфактический DOM из виртуального DOM? Как мне получить актуальную версию DOM для немедленного обновления?

Ответы [ 3 ]

0 голосов
/ 08 декабря 2018

Это работает почти так же, как и ожидалось, с сообщениями, совпадающими как до, так и после обновления DOM.

Я думаю, ваше понимание того, что вызов refs возвращает виртуальный узел, а не фактический элемент DOM, неверно.

new Vue({
  el: '#app',
  data: {
    isLoading: false
  },
  methods: {
    loadIt() {
      this.isLoading = true;
      this.tellMeAboutIt('before');
      this.$nextTick(() => this.tellMeAboutIt('after'));
    },
    tellMeAboutIt(when) {
        console.log(`Virtual ${when}:`, this.$refs.hey) // virtual DOM
        console.log(`Actual ${when}:`, document.getElementById('hey')) // actual DOM
    }
  }
});
<script src="https://unpkg.com/vue@latest/dist/vue.js"></script>
<div id="app">
  <div v-show="isLoading" id="hey" ref="hey">Loading...</div>
  <button @click="loadIt()">Load it</button>
</div>
0 голосов
/ 10 декабря 2018

Оказывается, что проблемы с кешем eslint-loader или кешем babel-loader вызвали эту странность.Я мог только исправить это, удалив все node_modules\.cache.Жаль, что я не знаю, почему это вообще произошло.

0 голосов
/ 07 декабря 2018

Пожалуйста, просмотрите Жизненный цикл Vue в документации.Следует отметить, что между этими двумя событиями существует разрыв.Также обратите внимание, что nextTick() ожидает следующего цикла обновления DOM, не обязательно виртуального DOM.

Обычно это решается с помощью ловушки жизненного цикла updated, которая выполняет код после виртуальный DOM уже обновлен.Если вам нужно выполнить какой-то код с гарантией того, что виртуальный DOM уже обновлен, вы можете сделать это там.

Возможно, вас также заинтересует реактивность по глубине .Это должно послужить хорошим дополнением к диаграмме жизненного цикла.

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