Kluczową koncepcją, którą należy zrozumieć, jest to, że DOM jest aktualizowany asynchronicznie . Kiedy zmieniasz wartość w Vue, zmiana nie jest natychmiast renderowana w DOM. Zamiast tego Vue kolejkuje aktualizację DOM, a następnie aktualizuje DOM według timera. Zwykle dzieje się to tak szybko, że nie robi różnicy, ale czasami trzeba zaktualizować wyrenderowany DOM po wyrenderowaniu go przez Vue, czego nie można od razu zrobić w metodzie, ponieważ aktualizacja nie nastąpiła jeszcze. W takich przypadkach użyjesz nextTick. Udokumentowane tutaj .
Bert
Uzupełniając to, co powiedział @Bert w https://stackoverflow.com/q/47634258/9979046 powyżej, metoda nextTick () zostanie użyta w testach jednostkowych, gdy trzeba sprawdzić, czy element istnieje w DOM (HTML), na przykład, jeśli otrzymasz informacje na temat wniosku Axios.
Oscar Alencar
dlaczego mam wrażenie, że nextTick jest czymś w rodzaju const nextTick = (callback, context) => { setTimeout(callback.bind(context), 0); };?
SparK
Odpowiedzi:
152
nextTick pozwala ci coś zrobić po zmianie danych i zaktualizowaniu przez VueJS DOM na podstawie zmian twoich danych, ale zanim przeglądarka wyrenderuje te zmiany na stronie.
Zwykle programiści używają natywnej funkcji JavaScript setTimeout, aby osiągnąć podobne zachowanie. Jednak użycie setTimeoutpowoduje zrzeczenie się kontroli nad przeglądarką, zanim przekaże ją z powrotem za pośrednictwem wywołania zwrotnego.
Powiedzmy, że zmieniłeś niektóre dane. Vue aktualizuje DOM na podstawie danych. Pamiętaj, że zmiany DOM nie są jeszcze renderowane na ekranie przez przeglądarkę. Jeśli użyłeś nextTick, oddzwonimy teraz. Następnie przeglądarka aktualizuje stronę. Jeśli użyjesz setTimeout, oddzwonienie zostanie wywołane dopiero teraz.
Możesz zwizualizować to zachowanie, tworząc mały komponent, taki jak następujący:
Dzieje się tak, ponieważ Vue zaktualizował DOM do Two, przekazując kontrolę przeglądarce. Wyświetlana przeglądarka Two. Następnie zadzwoniłem do twojego oddzwonienia. Vue zaktualizowało DOM do Three. Która przeglądarka wyświetliła się ponownie.
Z nextTick. Vue zmienił DOM na Two. Zadzwoniłem do twojego oddzwonienia. Vue zaktualizowało DOM do Three. Następnie przekazał kontrolę przeglądarce. I wyświetlona przeglądarka Three.
Mam nadzieję, że to było jasne.
Aby zrozumieć, jak Vue to implementuje, musisz zrozumieć koncepcję pętli zdarzeń i mikrozadań .
Jedna rzecz, której nie rozumiem, to kiedy mówisz „vue aktualizuje dane”, odnosisz się do zaktualizowanej wersji, np. this.name = 'foo'Czy odnosisz się do wstawienia elementów html na stronę?
hidar
Nie widzę w historii tego pytania gdzie on mówi „vue aktualizuje dane”… Mówi „Vue aktualizuje DOM na podstawie danych”. Oznacza to, że kiedy ustawiasz dane przez this.name = 'foo'vue, aktualizuje model obiektu dokumentu, aby odzwierciedlić zmiany wprowadzone w danych w oparciu o szablon i funkcje, które konfigurujesz.
Odroczenie wywołania zwrotnego po następnym cyklu aktualizacji DOM. Użyj go natychmiast po zmianie niektórych danych, aby poczekać na aktualizację DOM.
Hmm ... jeśli na początku wydaje się on onieśmielający, nie martw się, postaram się to wyjaśnić tak prosto, jak to tylko możliwe. Ale najpierw są dwie rzeczy, o których powinieneś wiedzieć:
Jego użycie jest rzadkie. Jak jedna z tych srebrnych magicznych kart. Napisałem kilka Vueaplikacji i raz lub dwa wpadłem na nextTick ().
Łatwiej jest to zrozumieć, gdy zobaczysz prawdziwe przypadki użycia. Gdy wpadniesz na pomysł, strach minie, a będziesz miał pod paskiem przydatne narzędzie.
W takim razie zróbmy to.
Zrozumienie $ nextTick
Jesteśmy programistami, prawda? Skorzystamy z naszego ukochanego podejścia dziel i podbijaj, aby spróbować przetłumaczyć opis .nextTick()po kawałku. Zaczyna się od:
Odłóż oddzwonienie
Ok, teraz wiemy, że akceptuje oddzwonienie. Więc wygląda to tak:
Vue.nextTick(function () {
// do something cool
});
Świetny. To oddzwonienie jest odroczone (tak mówią milenialsi) do…
następny cykl aktualizacji DOM.
W porządku. Wiemy, że Vue wykonuje aktualizacje DOM asynchronicznie . Zawiera sposób na przechowywanie tych aktualizacji do czasu ich zastosowania. Tworzy kolejkę aktualizacji i opróżnia ją w razie potrzeby. Następnie DOM jest „łatany” i aktualizowany do najnowszej wersji.
Co?
Spróbuję jeszcze raz: wyobraź sobie, że twój komponent robi coś naprawdę istotnego i inteligentnego, na przykład this.potatoAmount = 3.Vue nie wyrenderuje komponentu (a tym samym DOM) automatycznie. Ustawi w kolejce wymaganą modyfikację. Następnie w następnym „tyknięciu” (jak w zegarze) kolejka jest opróżniana, a aktualizacja jest stosowana. Tada!
W porządku! Wiemy więc, że możemy użyć nextTick()do przekazania funkcji zwrotnej, która jest wykonywana zaraz po ustawieniu danych i zaktualizowaniu DOM.
Jak powiedziałem wcześniej… nie tak często. Podejście „przepływu danych”, które napędza Vue, React i inne rozwiązanie od Google, o którym nie wspomnę, sprawia, że przez większość czasu jest to niepotrzebne. Jednak czasami musimy poczekać, aż niektóre elementy pojawią się / znikną / zostaną zmodyfikowane w DOM. Wtedy przydaje się nextTick.
Użyj go natychmiast po zmianie niektórych danych, aby poczekać na aktualizację DOM.
Dokładnie! To ostatnia definicja, którą dostarczyła nam dokumentacja Vue. Wewnątrz naszego wywołania zwrotnego DOM został zaktualizowany, abyśmy mogli wchodzić w interakcje z „najbardziej zaktualizowaną” jego wersją.
Udowodnij to
Dobrze, dobrze. Zobacz konsolę, a zobaczysz, że wartość naszych danych jest aktualizowana tylko w wywołaniu zwrotnym nextTick:
Spróbujmy zdefiniować kilka przydatnych przypadków użycia nextTick.
Wyobraź sobie, że musisz wykonać jakąś czynność po zamontowaniu komponentu. ALE! nie tylko komponent. Musisz także poczekać, aż wszystkie jego elementy podrzędne zostaną zamontowane i dostępne w DOM. Cholera! Nasz zamontowany hak nie gwarantuje renderowania całego drzewa komponentów.
Gdybyśmy tylko mieli narzędzie do czekania na kolejny cykl aktualizacji DOM…
Hahaa:
mounted() {
this.$nextTick(() => {
// The whole view is rendered, so I can safely access or query
// the DOM. ¯\_(ツ)_/¯
})
}
W skrócie
A więc: nextTickto wygodny sposób na wykonanie funkcji po ustawieniu danych i zaktualizowaniu modelu DOM.
Musisz poczekać na DOM, może dlatego, że musisz wykonać jakąś transformację lub musisz poczekać, aż zewnętrzna biblioteka załaduje swoje rzeczy? Następnie użyj nextTick.
Niektórzy ludzie używają również nextTick w swoich testach jednostkowych, aby upewnić się, że dane zostały zaktualizowane. W ten sposób mogą przetestować „zaktualizowaną wersję” komponentu.
Vue.nextTick () czy vm. $ NextTick ()?
Nie martw się. Obie są (prawie) takie same. Vue.nextTick()odnosi się do globalnej metody API, a vm.$nextTick()jest metodą instancji. Jedyna różnica polega na tym, vm.$nextTickże nie akceptuje kontekstu jako drugiego parametru. Zawsze jest do tego przypisana this(nazywana również samą instancją).
Ostatni kawałek chłodu
Zwróć uwagę, że nextTickzwraca a Promise, więc możemy przejść do końca async/awaiti ulepszyć przykład:
Po prostu dodaj oryginalnego autora i link u góry „Twojego” wyjaśnienia.
Renan Cidale
1
Co za niesamowite wyjaśnienie! Dziękuję bardzo za poświęcony czas i wysiłek.
Muaath Alhaddad
Cholera, właśnie skopiowałeś cały post z medium. Głosowano w dół.
Alexander Kim
Kiedy programiści szukają odpowiedzi w Google, StackOverflowwyniki są zwykle pierwsze, SO jest de facto miejscem, w którym można znaleźć odpowiedzi, ale istnieje wiele dobrych zasobów w Internecie, które mogą nie pojawiać się w wynikach wyszukiwania. Więc spędziłem prawie pół godziny na tę odpowiedź, to nie jest tylko kopiowanie, jak powiedziałeś, autorowi przypisywano od początku. Jeśli nie podoba ci się ten post, jest OK. Ale powinieneś szanować pracę innych
Humoyun Ahmad
16
Next Tick w zasadzie pozwala na uruchomienie jakiegoś kodu po tym, jak vue ponownie wyrenderuje komponent, gdy dokonałeś pewnych zmian we właściwości reaktywnej (danych).
// 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.
})
Z dokumentacji Vue.js:
Odroczenie wywołania zwrotnego po następnym cyklu aktualizacji DOM. Użyj go natychmiast po zmianie niektórych danych, aby poczekać na aktualizację DOM.
zaktualizować jak? tego nie rozumiem. jeśli zaktualizuję vm.msg, to dom jest już zaktualizowany, ponieważ jest nowy tekst „witaj” .. więc jak mogę go ponownie zaktualizować? czy możesz
wysłać
ok, poprawię odpowiedź i spróbuję to dokładniej wyjaśnić.
Daksh Miglani
@hidar możesz go używać w sytuacjach, gdy musisz wykonać wiele aktualizacji, ale chcesz jawnie renderować się nawzajem w różnych cyklach dom
Daksh Miglani,
Nie chodzi o to, abyś mógł aktualizować DOM jako taki, ale robić cokolwiek z nim (czy to aktualizować, czytać informacje z niego, itp.) Po zmianie / modyfikacji przez zmiany dokonane przez Vue (ponieważ zmieniłeś reaktywną wartość właściwości itp.).
zenw0lf
To był przykład, aby to uprościć.
Daksh Miglani
7
Aby uściślić odpowiedź Pranshata na temat różnicy między używaniem nextTick i setTimeout, bardziej precyzyjnie, rozwidliłem jego skrzypce:
tutaj
Możesz zobaczyć na skrzypcach, że podczas używania setTimeOut początkowe dane migają bardzo krótko po zamontowaniu komponentu przed dostosowaniem zmiany. Podczas gdy podczas korzystania z nextTick dane są przechwytywane, zmieniane przed renderowaniem do przeglądarki. Tak więc przeglądarka wyświetla zaktualizowane dane nawet bez znajomości starych. Mam nadzieję, że to wyjaśnia te dwie koncepcje za jednym zamachem.
nextTick
. Udokumentowane tutaj .const nextTick = (callback, context) => { setTimeout(callback.bind(context), 0); };
?Odpowiedzi:
nextTick pozwala ci coś zrobić po zmianie danych i zaktualizowaniu przez VueJS DOM na podstawie zmian twoich danych, ale zanim przeglądarka wyrenderuje te zmiany na stronie.
Zwykle programiści używają natywnej funkcji JavaScript setTimeout, aby osiągnąć podobne zachowanie. Jednak użycie
setTimeout
powoduje zrzeczenie się kontroli nad przeglądarką, zanim przekaże ją z powrotem za pośrednictwem wywołania zwrotnego.Powiedzmy, że zmieniłeś niektóre dane. Vue aktualizuje DOM na podstawie danych. Pamiętaj, że zmiany DOM nie są jeszcze renderowane na ekranie przez przeglądarkę. Jeśli użyłeś
nextTick
, oddzwonimy teraz. Następnie przeglądarka aktualizuje stronę. Jeśli użyjeszsetTimeout
, oddzwonienie zostanie wywołane dopiero teraz.Możesz zwizualizować to zachowanie, tworząc mały komponent, taki jak następujący:
Uruchom serwer lokalny. Zobaczysz wyświetlany komunikat
Three
.Teraz wymienić
this.$nextTick
zsetTimeout
Załaduj ponownie przeglądarkę. Zobaczysz
Two
, zanim zobaczyszThree
.Sprawdź to skrzypce, aby zobaczyć to na żywo
Dzieje się tak, ponieważ Vue zaktualizował DOM do
Two
, przekazując kontrolę przeglądarce. Wyświetlana przeglądarkaTwo
. Następnie zadzwoniłem do twojego oddzwonienia. Vue zaktualizowało DOM doThree
. Która przeglądarka wyświetliła się ponownie.Z
nextTick
. Vue zmienił DOM naTwo
. Zadzwoniłem do twojego oddzwonienia. Vue zaktualizowało DOM doThree
. Następnie przekazał kontrolę przeglądarce. I wyświetlona przeglądarkaThree
.Mam nadzieję, że to było jasne.
Aby zrozumieć, jak Vue to implementuje, musisz zrozumieć koncepcję pętli zdarzeń i mikrozadań .
Gdy już zrozumiesz te koncepcje, sprawdź kod źródłowy dla nextTick .
źródło
this.name = 'foo'
Czy odnosisz się do wstawienia elementów html na stronę?this.name = 'foo'
vue, aktualizuje model obiektu dokumentu, aby odzwierciedlić zmiany wprowadzone w danych w oparciu o szablon i funkcje, które konfigurujesz.Dokumentacja Vue mówi:
Hmm ... jeśli na początku wydaje się on onieśmielający, nie martw się, postaram się to wyjaśnić tak prosto, jak to tylko możliwe. Ale najpierw są dwie rzeczy, o których powinieneś wiedzieć:
Jego użycie jest rzadkie. Jak jedna z tych srebrnych magicznych kart. Napisałem kilka
Vue
aplikacji i raz lub dwa wpadłem na nextTick ().Łatwiej jest to zrozumieć, gdy zobaczysz prawdziwe przypadki użycia. Gdy wpadniesz na pomysł, strach minie, a będziesz miał pod paskiem przydatne narzędzie.
W takim razie zróbmy to.
Zrozumienie $ nextTick
Jesteśmy programistami, prawda? Skorzystamy z naszego ukochanego podejścia dziel i podbijaj, aby spróbować przetłumaczyć opis
.nextTick()
po kawałku. Zaczyna się od:Ok, teraz wiemy, że akceptuje oddzwonienie. Więc wygląda to tak:
Świetny. To oddzwonienie jest odroczone (tak mówią milenialsi) do…
W porządku. Wiemy, że Vue wykonuje aktualizacje DOM asynchronicznie . Zawiera sposób na przechowywanie tych aktualizacji do czasu ich zastosowania. Tworzy kolejkę aktualizacji i opróżnia ją w razie potrzeby. Następnie DOM jest „łatany” i aktualizowany do najnowszej wersji.
Co?
Spróbuję jeszcze raz: wyobraź sobie, że twój komponent robi coś naprawdę istotnego i inteligentnego, na przykład
this.potatoAmount = 3.
Vue nie wyrenderuje komponentu (a tym samym DOM) automatycznie. Ustawi w kolejce wymaganą modyfikację. Następnie w następnym „tyknięciu” (jak w zegarze) kolejka jest opróżniana, a aktualizacja jest stosowana. Tada!W porządku! Wiemy więc, że możemy użyć
nextTick()
do przekazania funkcji zwrotnej, która jest wykonywana zaraz po ustawieniu danych i zaktualizowaniu DOM.Jak powiedziałem wcześniej… nie tak często. Podejście „przepływu danych”, które napędza Vue, React i inne rozwiązanie od Google, o którym nie wspomnę, sprawia, że przez większość czasu jest to niepotrzebne. Jednak czasami musimy poczekać, aż niektóre elementy pojawią się / znikną / zostaną zmodyfikowane w DOM. Wtedy przydaje się nextTick.
Dokładnie! To ostatnia definicja, którą dostarczyła nam dokumentacja Vue. Wewnątrz naszego wywołania zwrotnego DOM został zaktualizowany, abyśmy mogli wchodzić w interakcje z „najbardziej zaktualizowaną” jego wersją.
Udowodnij to
Dobrze, dobrze. Zobacz konsolę, a zobaczysz, że wartość naszych danych jest aktualizowana tylko w wywołaniu zwrotnym nextTick:
const example = Vue.component('example', { template: '<p>{{ message }}</p>', data: function () { return { message: 'not updated' } }, mounted () { this.message = 'updated' console.log( 'outside nextTick callback:', this.$el.textContent ) // => 'not updated' this.$nextTick(() => { console.log( 'inside nextTick callback:', this.$el.textContent ) // => 'not updated' }) } }) new Vue({ el: '#app', render: h => h(example) })
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.10/vue.js"></script> <div id="app"></div>
Przypadek użycia
Spróbujmy zdefiniować kilka przydatnych przypadków użycia
nextTick
.Wyobraź sobie, że musisz wykonać jakąś czynność po zamontowaniu komponentu. ALE! nie tylko komponent. Musisz także poczekać, aż wszystkie jego elementy podrzędne zostaną zamontowane i dostępne w DOM. Cholera! Nasz zamontowany hak nie gwarantuje renderowania całego drzewa komponentów.
Gdybyśmy tylko mieli narzędzie do czekania na kolejny cykl aktualizacji DOM…
Hahaa:
W skrócie
A więc:
nextTick
to wygodny sposób na wykonanie funkcji po ustawieniu danych i zaktualizowaniu modelu DOM.Musisz poczekać na DOM, może dlatego, że musisz wykonać jakąś transformację lub musisz poczekać, aż zewnętrzna biblioteka załaduje swoje rzeczy? Następnie użyj nextTick.
Niektórzy ludzie używają również nextTick w swoich testach jednostkowych, aby upewnić się, że dane zostały zaktualizowane. W ten sposób mogą przetestować „zaktualizowaną wersję” komponentu.
Nie martw się. Obie są (prawie) takie same.
Vue.nextTick()
odnosi się do globalnej metody API, avm.$nextTick()
jest metodą instancji. Jedyna różnica polega na tym,vm.$nextTick
że nie akceptuje kontekstu jako drugiego parametru. Zawsze jest do tego przypisanathis
(nazywana również samą instancją).Ostatni kawałek chłodu
Zwróć uwagę, że
nextTick
zwraca aPromise
, więc możemy przejść do końcaasync/await
i ulepszyć przykład:źródło
StackOverflow
wyniki są zwykle pierwsze, SO jest de facto miejscem, w którym można znaleźć odpowiedzi, ale istnieje wiele dobrych zasobów w Internecie, które mogą nie pojawiać się w wynikach wyszukiwania. Więc spędziłem prawie pół godziny na tę odpowiedź, to nie jest tylko kopiowanie, jak powiedziałeś, autorowi przypisywano od początku. Jeśli nie podoba ci się ten post, jest OK. Ale powinieneś szanować pracę innychNext Tick w zasadzie pozwala na uruchomienie jakiegoś kodu po tym, jak vue ponownie wyrenderuje komponent, gdy dokonałeś pewnych zmian we właściwości reaktywnej (danych).
Z dokumentacji Vue.js:
Odroczenie wywołania zwrotnego po następnym cyklu aktualizacji DOM. Użyj go natychmiast po zmianie niektórych danych, aby poczekać na aktualizację DOM.
Przeczytaj więcej na ten temat tutaj .
źródło
Aby uściślić odpowiedź Pranshata na temat różnicy między używaniem nextTick i setTimeout, bardziej precyzyjnie, rozwidliłem jego skrzypce: tutaj
Możesz zobaczyć na skrzypcach, że podczas używania setTimeOut początkowe dane migają bardzo krótko po zamontowaniu komponentu przed dostosowaniem zmiany. Podczas gdy podczas korzystania z nextTick dane są przechwytywane, zmieniane przed renderowaniem do przeglądarki. Tak więc przeglądarka wyświetla zaktualizowane dane nawet bez znajomości starych. Mam nadzieję, że to wyjaśnia te dwie koncepcje za jednym zamachem.
źródło