Vue.$nextTick, ты действительно понимаешь? ? ?

Vue.js

В принципе будет больше слов, наберитесь терпения и смакуйте внимательно

В то же время эта статья основана на понимании цикла событий JS, поэтому, если вы не понимаете цикл событий, вы можете прочитать другую статью ниже 👉👉После прочтения цикла событий вы должны понять — Самородки (juejin.cn)

Механизм обновления DOM в Vue

Когда вы агрессивно используете Vue для демонстрации своих грандиозных планов, вы вдруг обнаруживаете, что, эй, я явно изменил эти данные, но когда я получил их, как было последнее значение (мне лень, поэтому я не буду приводить конкретные примеры 👵 )

В этот момент Vue скажет: «Пример, вы этого не понимаете, мой DOM обновляется асинхронно!!!»

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

В официальной документации Vue это указано следующим образом:

Если вы не заметили, Vue выполняет обновления DOM асинхронно. Как только будут обнаружены изменения данных, Vue откроет очередь и буферизует все изменения данных, которые происходят в том же цикле событий. Если один и тот же наблюдатель запускается несколько раз, он будет помещен в очередь только один раз. Эта дедупликация во время буферизации важна, чтобы избежать ненужных вычислений и манипуляций с DOM. Затем, в следующем цикле событий «тик», Vue очищает очередь и выполняет фактическую (дедублированную) работу.

Друзья, кто хочет узнать больше о принципе обновления DOM Vue, можете прочитать эту статьюПринцип асинхронного обновления Vue — Zhihu (zhihu.com)

Проще говоря, на самом деле это тесно связано с циклом событий в JS, то есть Vue не может отображать каждое изменение данных, он сначала поставит эти изменения в асинхронную очередь, а также будет дедуплицировать. операции в этой очереди.Например, если вы измените данные три раза, он сохранит только последний. Все эти изменения можно сохранить в виде очередей, поэтому возникает вопрос, когда vue изменяет DOM в цикле событий?

У Vue есть два варианта: один — выполнить обновление DOM в конце этого цикла событий, а другой — поместить обновление DOM в следующий раунд цикла событий. В это время Ю Юйси похлопал себя по груди и сказал: «У меня есть оба метода!» Но поскольку окончательное выполнение цикла событий этого раунда будет намного быстрее, чем цикл событий следующего раунда, Вью предпочитает первый. второй механизм срабатывает только тогда, когда среда его не поддерживает. (Ссылка в начале 👆👆 позволяет понять цикл событий)

Хотя производительность значительно улучшилась, в настоящее время возникает проблема.Все мы знаем, что в цикле событий, после завершения выполнения кода в стеке синхронного выполнения, будет выполнено содержимое в асинхронной очереди.Тогда наш Операция по получению DOM — это A sync! ! Это означает, что хоть я и изменил данные, но их обновление происходит асинхронно, и когда я их получу, они не успели измениться, поэтому в начале статьи будет проблема.

Этот. . . Мне нужно это сделать, так как мне это сделать? ?

Неважно, Ю Да очень любезен предоставить намVue.$nextTick()

Vue.$nextTick()

На самом деле, одно предложение может$nextTickЭта вещь дает понять: вы ставите$nextTick Операции в нем будут выполняться не сразу, а будут выполняться после завершения обновления данных и обновления DOM, так что то, что мы получаем, должно быть самым последним.

Чтобы быть более точным,$nextTickметод откладывает выполнение обратного вызова до завершения следующего цикла обновления DOM. (Если вы не понимаете это предложение, вы можете прочитать выше [собачья голова])

значит мы все понимаем$nextTickКак выполнить эту магическую функцию? Ядро состоит в следующем:

VueВнутренне попробуйте использовать родной для асинхронных очередейPromise.then,MutationObserverиsetImmediate, если среда выполнения не поддерживает его,setTimeout(fn, 0)заменять.

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

Для конкретного анализа исходного кода см.Вопрос из интервью: принцип $nextTick в Vue — Cloud + Community — Tencent Cloud (tencent.com)говорить очень четко

Я подытожу немного здесь: это$nextTickПоместите функцию обратного вызова в микрозадачу или макрозадачу, чтобы отсрочить порядок ее выполнения; (резюме также ленивое 👶)

Важно понимать значение трех его параметров в исходном коде:

  • callback: Операцию, которую мы хотим выполнить, можно поместить в эту функцию, мы ее ни разу не выполняли$nextTickФункция обратного вызова будет помещена в асинхронную очередь;
  • pending: идентификатор, используемый для определения того, происходит ли первое присоединение к циклу событий, и монтирование очереди для асинхронного выполнения запускается только при первом присоединении.
  • timerFunc: используется для запуска выполнения функции обратного вызова, т.е.Promise.thenилиMutationObserverилиsetImmediateилиsetTimeoutпроцесс

Поняв, посмотрев в целом$nextTickПроцесс выполнения внутри на самом деле поставить один за другим$nextTickФункция обратного вызова помещается в очередь обратных вызовов, а затем ожидает выполнения в соответствии с характером события.Когда наступает ее очередь выполнять, выполняйте ее, а затем удаляйте соответствующее событие из очереди обратных вызовов.

использовать

Сказав все это, как это использовать? очень просто очень просто

mounted: function () {
  this.$nextTick(function () {
    // Code that will run only after the
    // entire view has been rendered
  })
}

сцены, которые будут использоваться

  1. Операция получения DOM в созданном должна использовать его
  2. Это наш пример выше, если вы хотите получить последнее значение, используйте его
  3. Также есть некоторые сторонние плагины в процессе использования, ситуации использования, конкретного разбора конкретных проблем

Пополнить

Я не понял вопрос раньше,$nextTickТеперь, когда метод, который он передает, превратился в микрозадачу, каков порядок выполнения этой и других микрозадач?

Это просто кто монтирует первымPromiseпроблема с объектом, при вызове$nextTickметод, очередь выполнения, поддерживаемая внутри его замыкания, монтируется вPromiseобъект, когда данные обновляютсяVueВнутренне будет выполняться первым$nextTickметод, а затем подключите очередь выполнения кPromiseобъект, на самом деле понятьJsизEvent LoopПосле модели обновление данных также рассматривается как$nextTickвызов метода и понять$nextTickМетод будет выполнять все отправленные обратные вызовы одновременно, чтобы вы могли понять порядок выполнения.

и$nextTickиnextTickРазница в том,nextTickЕсть еще один параметр контекста для указания контекста. Но суть у обоих одна,$nextTickэто метод экземпляра,nextTickЭто всего лишь статический метод класса; одно из преимуществ методов экземпляра состоит в том, что они автоматически привязываются к вам как к вызывающему экземпляру.thisВот и все.

Ссылаться на:Почему Vue использует асинхронный рендеринг — WindrunnerMax — Blog Park (cnblogs.com)