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 !
Les éléments de principe auront plus de texte, soyez patient et savourez-le attentivement
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()
其实一句话就可以把$nextTick
这个东西讲明白:就是你放在$nextTick
当中的操作不会立即执行,而是等数据更新、DOM更新完成之后再执行,这样我们拿到的肯定就是最新的了。
再准确一点来讲就是$nextTick
方法将回调延迟到下次DOM更新循环之后执行。(看不懂这句人话的,可以看上面[狗头])
意思我们都懂了,那$nextTick
是怎样完成这个神奇的功能的呢? 核心如下:
Vue
在内部对异步队列尝试使用原生的Promise.then
、MutationObserver
和setImmediate
,如果执行环境不支持,则会采用setTimeout(fn, 0)
代替。
仔细地看这句话,你就可以发现这不就是利用 JavaScript 的这些异步回调任务队列,来实现 Vue 框架中自己的异步回调队列。这其实就是一个典型的将底层 JavaScript 执行原理应用到具体案例中的示例。
我在这里稍微总结一下:就是$nextTick
$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 : 🎜$nextTick
une fois $nextTick
就会把回调函数放到一个异步队列当中;Promise.then
或MutationObserver
或setImmediate
或setTimeout
的过程理解之后,在看整个$nextTick
里面的执行过程,其实就是把一个个$nextTick
中的回调函数压入到callback队列当中,然后根据事件的性质等待执行,轮到它执行的时候,就执行一下,然后去掉callback队列中相应的事件。
说了这么多,怎么用它呢? 很简单很简单
mounted: function () { this.$nextTick(function () { // Code that will run only after the // entire view has been rendered }) }
created中获取DOM的操作需要使用它
就是我们上面的例子,你如果想要获取最新值,就用它
还有一些第三方插件使用过程中,使用到的情况,具体问题具体分析
参考 前端进阶面试题详细解答
之前我一直搞不懂一个的问题,$nextTick
既然把它传入的方法变成微任务了,那它和其它微任务的执行顺序是怎样的呢?
这简单来说就是谁先挂载Promise
对象的问题,在调用$nextTick
方法时就会将其闭包内部维护的执行队列挂载到Promise
对象,在数据更新时Vue
内部首先就会执行$nextTick
方法,之后便将执行队列挂载到了Promise
对象上,其实在明白Js
的Event Loop
模型后,将数据更新也看做一个$nextTick
方法的调用,并且明白$nextTick
方法会一次性执行所有推入的回调,就可以明白执行顺序的问题了
还有$nextTick
和nextTick
区别就是nextTick
多了一个context参数,用来指定上下文。但两个的本质是一样的,$nextTick
是实例方法,nextTick
是类的静态方法而已;实例方法的一个好处就是,自动给你绑定为调用实例的this
ending: 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
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 simplerrreeeScénario d'utilisation
$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 $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!