Maison > interface Web > Voir.js > Vous amène à avoir une compréhension plus approfondie de Vue.$nextTick (une brève analyse du principe)

Vous amène à avoir une compréhension plus approfondie de Vue.$nextTick (une brève analyse du principe)

青灯夜游
Libérer: 2023-03-01 20:03:37
avant
2100 Les gens l'ont consulté

Cet article partagera avec vous la connaissance pure de Vue, présentera Vue.nextTick que vous ne connaissez pas et parlera du principe de Vue.$nextTick. J'espère qu'il sera utile à tout le monde !

Vous amène à avoir une compréhension plus approfondie de Vue.$nextTick (une brève analyse du principe)

Les éléments de principe auront plus de texte, soyez patient et savourez-le attentivement

Mécanisme de mise à jour DOM dans Vue

Lorsque vous utilisez Vue de manière agressive pour réaliser vos ambitions, vous découvrez soudainement, hein, j'ai évidemment a changé ces données, mais quand je les reçois, pourquoi est-ce la dernière valeur (je suis paresseux, donc je ne donnerai pas d'exemple précis ?)

À ce moment-là, Vue dira : "Échantillon, voilà, je ne Je ne comprends pas, mon DOM est mis à jour de manière asynchrone ! »

En termes simples, la réactivité de Vue modifie non seulement le DOM immédiatement après les modifications des données, mais modifie également le DOM selon une certaine stratégie de mises à jour. L’avantage est que cela permet d’éviter certaines opérations inutiles sur le DOM et d’améliorer les performances de rendu. [Recommandations associées : Tutoriel vidéo Vuejs, Développement web front-end]

Ceci est expliqué dans la documentation officielle de Vue :

Peut-être n'avez-vous pas remarqué que Vue effectue les mises à jour du DOM de manière asynchrone. Tant que des modifications de données sont observées, Vue ouvrira une file d'attente et mettra en mémoire tampon toutes les modifications de données qui se produisent dans la même boucle d'événements. Si le même observateur est déclenché plusieurs fois, il ne sera placé dans la file d'attente qu'une seule fois. Cette déduplication lors de la mise en mémoire tampon est très importante pour éviter les calculs et opérations DOM inutiles. Ensuite, lors de la prochaine boucle d'événement "tick", Vue vide la file d'attente et effectue le travail réel (dédupliqué).

Pour le dire franchement, cela est en fait étroitement lié à la boucle d'événements dans JS, c'est-à-dire que Vue ne peut pas restituer toutes les modifications de données. Il placera d'abord ces modifications dans une file d'attente asynchrone, et en même temps, il déduuplera également. les opérations dans cette file d'attente. Par exemple, si vous modifiez les données trois fois, seule la dernière sera conservée. Ces modifications peuvent être enregistrées sous forme de file d'attente. Maintenant, la question se pose : à quel moment de la boucle d'événements Vue modifie-t-il le DOM ?

Vue a deux options, l'une consiste à mettre à jour le DOM à la fin de cette boucle d'événements et l'autre consiste à placer la mise à jour du DOM au prochain tour de boucle d'événements. zÀ ce moment-là, You Yuxi lui a tapoté la poitrine et a dit : « J'ai les deux méthodes ! » Cependant, comme l'exécution finale de ce tour de boucle d'événements sera beaucoup plus rapide que le prochain tour de boucle d'événements, Vue donne la priorité à la première méthode. , le deuxième mécanisme ne se déclenche que lorsque l'environnement ne le supporte pas. (Le lien commençant par ?? vous permet de comprendre la boucle d'événement)

Bien que les performances aient été beaucoup améliorées, des problèmes surviennent à ce moment-là. Nous savons tous que dans un tour de boucle d'événement, après l'exécution du code dans le fichier. la pile d'exécution synchrone est terminée, Exécution du contenu de la file d'attente asynchrone, alors notre opération d'obtention du DOM est synchrone ! ! Cela ne signifierait-il pas que même si j'ai modifié les données, leur mise à jour est asynchrone, et lorsque je les obtiens, elles n'ont pas eu le temps de changer, donc le problème au début de l'article se produira.

Ceci. . . J'ai vraiment besoin de faire ça, alors que dois-je faire ? ?

Peu importe, Youda nous a très gentiment fourni Vue.$nextTick()Vue.$nextTick()

Vue.$nextTick()

其实一句话就可以把$nextTick这个东西讲明白:就是你放在$nextTick 当中的操作不会立即执行,而是等数据更新、DOM更新完成之后再执行,这样我们拿到的肯定就是最新的了。

再准确一点来讲就是$nextTick方法将回调延迟到下次DOM更新循环之后执行。(看不懂这句人话的,可以看上面[狗头])

意思我们都懂了,那$nextTick是怎样完成这个神奇的功能的呢? 核心如下:

Vue在内部对异步队列尝试使用原生的Promise.thenMutationObserversetImmediate,如果执行环境不支持,则会采用 setTimeout(fn, 0)代替。

仔细地看这句话,你就可以发现这不就是利用 JavaScript 的这些异步回调任务队列,来实现 Vue 框架中自己的异步回调队列。这其实就是一个典型的将底层 JavaScript 执行原理应用到具体案例中的示例。

我在这里稍微总结一下:就是$nextTick

Vue.$nextTick()

🎜 En fait, une phrase peut expliquer clairement $nextTick : l'opération que vous mettez dans $nextTick ne sera pas exécutée immédiatement, mais attendra que la mise à jour des données et la mise à jour du DOM soient effectuées. terminé. Exécutez-le plus tard, afin que ce que nous obtenons soit définitivement le dernier. 🎜🎜Pour être plus précis, la méthode $nextTick retarde l'exécution du rappel jusqu'au prochain cycle de mise à jour du DOM. (Si vous ne comprenez pas cette phrase, vous pouvez lire [tête de chien] ci-dessus) 🎜🎜Nous comprenons tous le sens, alors comment $nextTick accomplit-il cette fonction magique ? Le noyau est le suivant : 🎜🎜🎜Vue essaie en interne d'utiliser Promise.then natif, MutationObserver et setImmediate pour les files d'attente asynchrones >, si l'environnement d'exécution ne le prend pas en charge, setTimeout(fn, 0) sera utilisé à la place. 🎜🎜🎜Regardez attentivement cette phrase, et vous constaterez qu'il ne s'agit pas simplement d'utiliser ces files d'attente de tâches de rappel asynchrones de JavaScript pour implémenter votre propre file d'attente de rappel asynchrone dans le framework Vue. Il s'agit en fait d'un exemple typique d'application des principes d'exécution JavaScript sous-jacents à un cas spécifique. 🎜🎜Laissez-moi résumer un peu ici : $nextTick met la fonction de rappel dans une micro-tâche ou une macro-tâche pour retarder son ordre d'exécution (le résumé est-il trop paresseux ?) 🎜🎜Le l'important est de comprendre la signification de ses trois paramètres dans le code source : 🎜
  • callback : L'opération que nous voulons effectuer peut être placée dans cette fonction. Nous mettrons la fonction de rappel dans une file d'attente asynchrone avant d'exécuter $nextTick une fois
  • $nextTick就会把回调函数放到一个异步队列当中;
  • pending:标识,用以判断在某个事件循环中是否为第一次加入,第一次加入的时候才触发异步执行的队列挂载
  • timerFunc:用来触发执行回调函数,也就是Promise.thenMutationObserversetImmediatesetTimeout的过程

理解之后,在看整个$nextTick里面的执行过程,其实就是把一个个$nextTick中的回调函数压入到callback队列当中,然后根据事件的性质等待执行,轮到它执行的时候,就执行一下,然后去掉callback队列中相应的事件。

使用

说了这么多,怎么用它呢? 很简单很简单

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

使用场景

  • created中获取DOM的操作需要使用它

  • 就是我们上面的例子,你如果想要获取最新值,就用它

  • 还有一些第三方插件使用过程中,使用到的情况,具体问题具体分析

参考 前端进阶面试题详细解答

补充

之前我一直搞不懂一个的问题,$nextTick既然把它传入的方法变成微任务了,那它和其它微任务的执行顺序是怎样的呢?

这简单来说就是谁先挂载Promise对象的问题,在调用$nextTick方法时就会将其闭包内部维护的执行队列挂载到Promise对象,在数据更新时Vue内部首先就会执行$nextTick方法,之后便将执行队列挂载到了Promise对象上,其实在明白JsEvent Loop模型后,将数据更新也看做一个$nextTick方法的调用,并且明白$nextTick方法会一次性执行所有推入的回调,就可以明白执行顺序的问题了

还有$nextTicknextTick区别就是nextTick多了一个context参数,用来指定上下文。但两个的本质是一样的,$nextTick是实例方法,nextTick是类的静态方法而已;实例方法的一个好处就是,自动给你绑定为调用实例的thisending: identification , used; pour déterminer si c'est la première fois que l'on rejoint une boucle d'événement. Le montage de la file d'attente pour l'exécution asynchrone n'est déclenché que lorsque la première fois est ajoutée

timerFunc : utilisé pour déclencher la fonction de rappel d'exécution, c'est-à-dire Le processus de Promise.then ou MutationObserver ou setImmediate ou setTimeout

Après avoir compris, regardez L'ensemble du processus d'exécution dans $nextTick consiste en fait à pousser les fonctions de rappel dans $nextTick dans la file d'attente de rappel, puis à attendre l'exécution en fonction de la nature de l'événement. . Lorsqu'il est exécuté, il est exécuté puis l'événement correspondant dans la file d'attente de rappel est supprimé.

Utiliser

Cela dit, comment l'utiliser ? Très simple, très simplerrreee

Scénario d'utilisation

    créé Vous devez l'utiliser pour obtenir le DOM🎜🎜🎜C'est notre exemple ci-dessus. Si vous souhaitez obtenir la dernière valeur, utilisez-la🎜🎜🎜Il existe également des plug-ins tiers. qui sont utilisés lors de la situation d'utilisation, analyse spécifique de problèmes spécifiques 🎜🎜RéférenceRéponses détaillées aux questions d'entretien avancées frontales🎜🎜

    Supplémentaire

    🎜Je n'ai jamais été capable de comprendre une question auparavant. Puisque $nextTick a transformé sa méthode entrante en microtâche, quel est l'ordre dans lequel elle et les autres microtâches se trouvent. exécuté? 🎜🎜Il s'agit simplement de savoir qui monte l'objet Promise en premier. Lorsque la méthode $nextTick est appelée, la file d'attente d'exécution maintenue à l'intérieur de sa fermeture sera montée sur Promise, lorsque les données sont mises à jour, <code>Vue exécutera d'abord la méthode $nextTick en interne, puis montera la file d'attente d'exécution sur Promise , en fait, après avoir compris le modèle <code>Event Loop de Js, la mise à jour des données est également considérée comme un appel au $nextTick et comprenez que la méthode $nextTick exécutera tous les rappels poussés en même temps, vous pouvez comprendre le problème de l'ordre d'exécution🎜🎜Il existe également $nextTick et nextTickLa différence est que <code>nextTick a un paramètre de contexte supplémentaire pour spécifier le contexte. Mais l'essence des deux est la même. $nextTick est une méthode d'instance, et nextTick n'est qu'une méthode statique de la classe. L'un des avantages de la méthode d'instance est que. il vous est automatiquement lié. Appelez simplement this de l'instance. 🎜🎜 (Partage de vidéos d'apprentissage : 🎜Tutoriel d'introduction à vuejs🎜, 🎜Vidéo de programmation de base🎜)🎜

    Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

    Étiquettes associées:
    source:juejin.cn
    Déclaration de ce site Web
    Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
    Tutoriels populaires
    Plus>
    Derniers téléchargements
    Plus>
    effets Web
    Code source du site Web
    Matériel du site Web
    Modèle frontal