Leo los documentos, pero no puedo entenderlos. Sé lo que hacen los métodos de datos, calculados, de observación, pero ¿ nextTick()para qué sirven en vuejs?
El concepto clave a comprender es que el DOM se actualiza de forma asincrónica . Cuando cambia un valor en Vue, el cambio no se representa inmediatamente en el DOM. En cambio, Vue pone en cola una actualización de DOM y luego, en un temporizador, actualiza el DOM. Normalmente, esto sucede tan rápido que no hace ninguna diferencia, pero, a veces, es necesario actualizar el DOM renderizado después de que Vue lo ha renderizado, lo que no puede hacer de inmediato en un método porque la actualización no ha ocurrido. todavía. En esos casos, usaría nextTick. Documentado aquí .
Bert
Complementando lo que dijo @Bert en https://stackoverflow.com/q/47634258/9979046 arriba, el nextTick () se utilizará en las pruebas unitarias, cuando necesite verificar si un elemento existe en DOM (HTML), por ejemplo, si obtiene información sobre una solicitud de Axios.
Oscar Alencar
Respuestas:
138
nextTick le permite hacer algo después de haber cambiado los datos y VueJS ha actualizado el DOM en función de su cambio de datos, pero antes de que el navegador haya presentado los cambios en la página.
Digamos que cambió algunos datos. Vue actualiza DOM en función de los datos. Tenga en cuenta que el navegador aún no muestra los cambios en el DOM en la pantalla. Si lo utilizó nextTick, su devolución de llamada se llama ahora. Luego, el navegador actualiza la página. Si lo utiliza setTimeout, su devolución de llamada se llamará solo ahora.
Puede visualizar este comportamiento creando un pequeño componente como el siguiente:
Eso es porque, Vue actualizó el DOM a Two, le dio control al navegador. Se muestra el navegador Two. Luego, llamó a su devolución de llamada. Vue actualizó el DOM a Three. Que el navegador volvió a mostrar.
Con nextTick. Vue actualizó el DOM a Two. Llamado a su devolución de llamada. Vue actualizó el DOM a Three. Luego le dio el control al navegador. Y se muestra el navegador Three.
Espero que haya quedado claro.
Para comprender cómo Vue implementa esto, debe comprender el concepto de Event Loop y microtasks .
Una cosa que no entiendo es que cuando dices "vue actualiza los datos", ¿te refieres a la actualización realizada con ex: this.name = 'foo'o te refieres a la inyección de elementos html en la página?
hidar
No veo en ningún lugar del historial de esta pregunta donde diga "vue actualiza los datos" ... Sí dice "Vue actualiza DOM basado en los datos". Lo que significa que cuando configuras datos a través de this.name = 'foo'vue, se actualiza el modelo de objetos del documento para reflejar los cambios realizados en los datos según la plantilla y las funciones que configuras.
Aplaza la ejecución de la devolución de llamada después del próximo ciclo de actualización del DOM. Úselo inmediatamente después de haber cambiado algunos datos para esperar la actualización del DOM.
Hmm ..., si te parece intimidante al principio, no te preocupes, intentaré explicártelo de la forma más sencilla posible. Pero primero hay 2 cosas que debes saber:
Su uso es poco común. Como una de esas cartas mágicas plateadas. He escrito varias Vueaplicaciones y encontré nextTick () una o dos veces.
Es más fácil de entender una vez que haya visto algunos casos de uso reales. Una vez que tenga la idea, el miedo desaparecerá y tendrá una herramienta útil en su haber.
Vamos a por ello, entonces.
Entendiendo $ nextTick
Somos programadores, ¿no? Usaremos nuestro amado enfoque de dividir y conquistar para tratar de traducir la descripción .nextTick()poco a poco. Empieza con:
Aplazar la devolución de llamada
Bien, ahora sabemos que acepta una devolución de llamada. Entonces se ve así:
Vue.nextTick(function () {
// do something cool
});
Excelente. Esta devolución de llamada se aplaza (así es como los millenials dicen que se retrasa) hasta ...
el próximo ciclo de actualización del DOM.
Bueno. Sabemos que Vue realiza actualizaciones DOM de forma asincrónica . Cuenta con una forma de mantener estas actualizaciones "almacenadas" hasta que sea necesario aplicarlas. Crea una cola de actualizaciones y la vacía cuando es necesario. Luego, el DOM es "parcheado" y actualizado a su última versión.
¿Qué?
Déjame intentarlo de nuevo: imagina que tu componente hace algo realmente esencial e inteligente, como que this.potatoAmount = 3.Vue no volverá a renderizar el componente (y por lo tanto el DOM) automáticamente. Pondrá en cola la modificación requerida. Luego, en el siguiente "tic" (como en un reloj), la cola se vacía y se aplica la actualización. Tada!
¡Bueno! Entonces sabemos que podemos usar nextTick()para pasar una función de devolución de llamada que se ejecuta justo después de que se establecen los datos y se actualiza el DOM.
Como dije antes… no tan a menudo. El enfoque de "flujo de datos" que impulsa a Vue, React y el otro de Google, que no mencionaré, lo hace innecesario la mayor parte del tiempo. Sin embargo, a veces necesitamos esperar a que algunos elementos aparezcan / desaparezcan / se modifiquen en el DOM. Aquí es cuando nextTick resulta útil.
Úselo inmediatamente después de haber cambiado algunos datos para esperar la actualización del DOM.
¡Exactamente! Esta es la última pieza de definición que nos proporcionaron los documentos de Vue. Dentro de nuestra devolución de llamada, el DOM se ha actualizado para que podamos interactuar con la versión "más actualizada".
Pruébalo
Bien bien. Vea la consola y verá que el valor de nuestros datos se actualiza solo dentro de la devolución de llamada de nextTick:
Intentemos definir algún caso de uso útil para nextTick.
Imagine que necesita realizar alguna acción cuando se monta un componente. ¡PERO! no solo el componente. También debe esperar hasta que todos sus elementos secundarios estén montados y disponibles en el DOM. ¡Maldición! Nuestro gancho montado no garantiza que se procese todo el árbol de componentes.
Si tan solo tuviéramos una herramienta para esperar el próximo ciclo de actualización del DOM ...
Jaja:
mounted() {
this.$nextTick(() => {
// The whole view is rendered, so I can safely access or query
// the DOM. ¯\_(ツ)_/¯
})
}
En una palabra
Entonces: nextTickes una forma cómoda de ejecutar una función después de que se hayan configurado los datos y se haya actualizado el DOM.
¿Necesita esperar al DOM, tal vez porque necesita realizar alguna transformación o necesita esperar a que una biblioteca externa cargue sus cosas? Luego use nextTick.
Algunas personas también usan nextTick en sus pruebas unitarias como una forma de asegurarse de que los datos se hayan actualizado. De esta manera, pueden probar la "versión actualizada" del componente.
Vue.nextTick () o vm. $ NextTick ()?
No se preocupe. Ambos son (casi) iguales. Vue.nextTick()se refiere al método API global, mientras que vm.$nextTick()es un método de instancia. La única diferencia es que vm.$nextTickno acepta un contexto como segundo parámetro. Siempre está vinculado a this(también conocido como la propia instancia).
Un último trozo de frescura
Observe que nextTickdevuelve unPromise , por lo que podemos enfriarnos completamente async/awaity mejorar el ejemplo:
Simplemente agregue el autor original y el enlace, en la parte superior de "su" explicación.
Renan Cidale
1
¡Qué explicación más asombrosa! Muchas gracias por su tiempo y esfuerzo.
Muaath Alhaddad
16
Next Tick básicamente le permite ejecutar algún código, después de que vue haya vuelto a renderizar el componente cuando haya realizado algunos cambios en la propiedad reactiva (datos).
// modify data
vm.msg = 'Hello'
// DOM not updated yet
Vue.nextTick(function () {
// this function is called when vue has re-rendered the component.
})
// usage as a promise (2.1.0+, see note below)
Vue.nextTick()
.then(function () {
// this function is called when vue has re-rendered the component.
})
De la documentación de Vue.js:
Aplaza la ejecución de la devolución de llamada después del próximo ciclo de actualización del DOM. Úselo inmediatamente después de haber cambiado algunos datos para esperar la actualización del DOM.
actualizarlo como? esto es lo que no entiendo. si actualizo vm.msg, entonces el dom ya está actualizado porque hay un nuevo texto "hola" ... entonces, ¿cómo puedo actualizarlo de nuevo? ¿Pueden publicar un violín con un ejemplo por favor? Gracias
hidar
está bien, editaré la respuesta e intentaré explicarla más.
Daksh Miglani
@hidar, puede usarlo en situaciones en las que tiene que hacer varias actualizaciones, pero desea renderizar explícitamente entre sí en diferentes ciclos de dom
Daksh Miglani
No es para permitirle actualizar el DOM per se, sino para hacer cualquier cosa con él (ya sea actualizar, leer información de él, etc.) después de que se haya visto afectado / modificado por los cambios realizados por Vue (porque cambió un valor de propiedad reactiva , etc.).
zenw0lf
Ese fue un ejemplo para hacerlo más simple.
Daksh Miglani
7
Para hacer que la respuesta de Pranshat sobre la diferencia entre usar nextTick y setTimeout, sea más explícita, he bifurcado su violín:
aquí
Puede ver en el violín que cuando se usa setTimeOut, los datos iniciales parpadean muy brevemente una vez que se monta el componente antes de adaptar el cambio. Mientras que, cuando se usa nextTick, los datos se secuestran, cambian, antes de procesarlos en el navegador. Entonces, el navegador muestra los datos actualizados sin siquiera tener conocimiento de los antiguos. Espero que aclare los dos conceptos de una sola vez.
nextTick
. Documentado aquí .Respuestas:
nextTick le permite hacer algo después de haber cambiado los datos y VueJS ha actualizado el DOM en función de su cambio de datos, pero antes de que el navegador haya presentado los cambios en la página.
Normalmente, los desarrolladores usan la función nativa de JavaScript setTimeout para lograr un comportamiento similar. Pero, el uso
setTimeout
cede el control al navegador antes de que le devuelva el control a través de su devolución de llamada.Digamos que cambió algunos datos. Vue actualiza DOM en función de los datos. Tenga en cuenta que el navegador aún no muestra los cambios en el DOM en la pantalla. Si lo utilizó
nextTick
, su devolución de llamada se llama ahora. Luego, el navegador actualiza la página. Si lo utilizasetTimeout
, su devolución de llamada se llamará solo ahora.Puede visualizar este comportamiento creando un pequeño componente como el siguiente:
Ejecute su servidor local. Verá el mensaje que
Three
se muestra.Ahora, reemplace su
this.$nextTick
consetTimeout
Vuelve a cargar el navegador. Verás
Two
, antes de verThree
.Mira este violín para verlo en vivo
Eso es porque, Vue actualizó el DOM a
Two
, le dio control al navegador. Se muestra el navegadorTwo
. Luego, llamó a su devolución de llamada. Vue actualizó el DOM aThree
. Que el navegador volvió a mostrar.Con
nextTick
. Vue actualizó el DOM aTwo
. Llamado a su devolución de llamada. Vue actualizó el DOM aThree
. Luego le dio el control al navegador. Y se muestra el navegadorThree
.Espero que haya quedado claro.
Para comprender cómo Vue implementa esto, debe comprender el concepto de Event Loop y microtasks .
Una vez que tenga esos conceptos claros (más), verifique el código fuente de nextTick .
fuente
this.name = 'foo'
o te refieres a la inyección de elementos html en la página?this.name = 'foo'
vue, se actualiza el modelo de objetos del documento para reflejar los cambios realizados en los datos según la plantilla y las funciones que configuras.La documentación de Vue dice:
Hmm ..., si te parece intimidante al principio, no te preocupes, intentaré explicártelo de la forma más sencilla posible. Pero primero hay 2 cosas que debes saber:
Su uso es poco común. Como una de esas cartas mágicas plateadas. He escrito varias
Vue
aplicaciones y encontré nextTick () una o dos veces.Es más fácil de entender una vez que haya visto algunos casos de uso reales. Una vez que tenga la idea, el miedo desaparecerá y tendrá una herramienta útil en su haber.
Vamos a por ello, entonces.
Entendiendo $ nextTick
Somos programadores, ¿no? Usaremos nuestro amado enfoque de dividir y conquistar para tratar de traducir la descripción
.nextTick()
poco a poco. Empieza con:Bien, ahora sabemos que acepta una devolución de llamada. Entonces se ve así:
Excelente. Esta devolución de llamada se aplaza (así es como los millenials dicen que se retrasa) hasta ...
Bueno. Sabemos que Vue realiza actualizaciones DOM de forma asincrónica . Cuenta con una forma de mantener estas actualizaciones "almacenadas" hasta que sea necesario aplicarlas. Crea una cola de actualizaciones y la vacía cuando es necesario. Luego, el DOM es "parcheado" y actualizado a su última versión.
¿Qué?
Déjame intentarlo de nuevo: imagina que tu componente hace algo realmente esencial e inteligente, como que
this.potatoAmount = 3.
Vue no volverá a renderizar el componente (y por lo tanto el DOM) automáticamente. Pondrá en cola la modificación requerida. Luego, en el siguiente "tic" (como en un reloj), la cola se vacía y se aplica la actualización. Tada!¡Bueno! Entonces sabemos que podemos usar
nextTick()
para pasar una función de devolución de llamada que se ejecuta justo después de que se establecen los datos y se actualiza el DOM.Como dije antes… no tan a menudo. El enfoque de "flujo de datos" que impulsa a Vue, React y el otro de Google, que no mencionaré, lo hace innecesario la mayor parte del tiempo. Sin embargo, a veces necesitamos esperar a que algunos elementos aparezcan / desaparezcan / se modifiquen en el DOM. Aquí es cuando nextTick resulta útil.
¡Exactamente! Esta es la última pieza de definición que nos proporcionaron los documentos de Vue. Dentro de nuestra devolución de llamada, el DOM se ha actualizado para que podamos interactuar con la versión "más actualizada".
Pruébalo
Bien bien. Vea la consola y verá que el valor de nuestros datos se actualiza solo dentro de la devolución de llamada de nextTick:
Un caso de uso
Intentemos definir algún caso de uso útil para
nextTick
.Imagine que necesita realizar alguna acción cuando se monta un componente. ¡PERO! no solo el componente. También debe esperar hasta que todos sus elementos secundarios estén montados y disponibles en el DOM. ¡Maldición! Nuestro gancho montado no garantiza que se procese todo el árbol de componentes.
Si tan solo tuviéramos una herramienta para esperar el próximo ciclo de actualización del DOM ...
Jaja:
En una palabra
Entonces:
nextTick
es una forma cómoda de ejecutar una función después de que se hayan configurado los datos y se haya actualizado el DOM.¿Necesita esperar al DOM, tal vez porque necesita realizar alguna transformación o necesita esperar a que una biblioteca externa cargue sus cosas? Luego use nextTick.
Algunas personas también usan nextTick en sus pruebas unitarias como una forma de asegurarse de que los datos se hayan actualizado. De esta manera, pueden probar la "versión actualizada" del componente.
No se preocupe. Ambos son (casi) iguales.
Vue.nextTick()
se refiere al método API global, mientras quevm.$nextTick()
es un método de instancia. La única diferencia es quevm.$nextTick
no acepta un contexto como segundo parámetro. Siempre está vinculado athis
(también conocido como la propia instancia).Un último trozo de frescura
Observe que
nextTick
devuelve unPromise
, por lo que podemos enfriarnos completamenteasync/await
y mejorar el ejemplo:fuente
Next Tick básicamente le permite ejecutar algún código, después de que vue haya vuelto a renderizar el componente cuando haya realizado algunos cambios en la propiedad reactiva (datos).
De la documentación de Vue.js:
Aplaza la ejecución de la devolución de llamada después del próximo ciclo de actualización del DOM. Úselo inmediatamente después de haber cambiado algunos datos para esperar la actualización del DOM.
Lea más sobre esto aquí .
fuente
Para hacer que la respuesta de Pranshat sobre la diferencia entre usar nextTick y setTimeout, sea más explícita, he bifurcado su violín: aquí
Puede ver en el violín que cuando se usa setTimeOut, los datos iniciales parpadean muy brevemente una vez que se monta el componente antes de adaptar el cambio. Mientras que, cuando se usa nextTick, los datos se secuestran, cambian, antes de procesarlos en el navegador. Entonces, el navegador muestra los datos actualizados sin siquiera tener conocimiento de los antiguos. Espero que aclare los dos conceptos de una sola vez.
fuente