NextTick nedir veya VueJ'lerde ne işe yarar?


121

Belgeleri okudum ama anlayamıyorum. Hangi verilerin, hesaplanan, izlenen, yöntemlerin işe yaradığını biliyorum ama nextTick()vuej'lerde ne için kullanılır?


21
Anlaşılması gereken temel kavram, DOM'un eşzamansız olarak güncellenmesidir . Vue'da bir değeri değiştirdiğinizde, değişiklik hemen DOM'a işlenmez. Bunun yerine, Vue bir DOM güncellemesini sıraya koyar ve ardından bir zamanlayıcıda DOM'u günceller. Normalde, bu o kadar hızlı gerçekleşir ki bir fark yaratmaz, ancak bazen, oluşturulan DOM'u Vue oluşturduktan sonra güncellemeniz gerekir, çünkü güncelleme gerçekleşmediğinden bunu bir yöntemde hemen yapamazsınız. hala. Bu durumlarda kullanırsınız nextTick. Burada belgelenmiştir .
Bert

@Bert'in yukarıdaki https://stackoverflow.com/q/47634258/9979046'da söylediklerini tamamlayan nextTick (), örneğin DOM (HTML) içinde bir öğenin olup olmadığını kontrol etmeniz gerektiğinde Birim Testlerinde kullanılacaktır. Axios talebi hakkında biraz bilgi alırsanız.
Oscar Alencar

neden nextTick'in bir şeye benzediğini hissediyorum const nextTick = (callback, context) => { setTimeout(callback.bind(context), 0); };?
SparK

Yanıtlar:


155

nextTick , verileri değiştirdikten sonra ve VueJS, DOM'u veri değişikliğinize göre güncelledikten sonra, ancak tarayıcı sayfada değiştirilenleri oluşturmadan önce bir şeyler yapmanıza izin verir.

Normalde geliştiriciler , benzer davranışa ulaşmak için yerel JavaScript işlevi setTimeout kullanır. Ancak kullanmak setTimeout, geri arama yoluyla kontrolü size geri vermeden önce tarayıcının denetiminden vazgeçer.

Diyelim ki bazı verileri değiştirdiniz. Vue, verilere göre DOM'u günceller. DOM değişikliklerinin henüz tarayıcı tarafından ekrana yansıtılmadığını unutmayın. Kullandıysanız nextTick, geri aramanız şimdi aranır. Ardından tarayıcı sayfayı günceller. Eğer kullanılırsa setTimeout, geri arama ancak şimdi denilen olsun istiyorum.

Aşağıdaki gibi küçük bir bileşen oluşturarak bu davranışı görselleştirebilirsiniz:

<template>
  <div class="hello">
    {{ msg }}
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  data() {
    return {
        msg: 'One'
    }
  },
  mounted() {
      this.msg = 'Two';

      this.$nextTick(() => {
          this.msg = 'Three';
      });
  }
}
</script>

Yerel sunucunuzu çalıştırın. ThreeGörüntülenen mesajı göreceksiniz.

Şimdi senin this.$nextTickyerinesetTimeout

setTimeout(() => {
    this.msg = 'Three';
}, 0);

Tarayıcıyı yeniden yükleyin. Sen Twogörmeden göreceksin Three.

Canlı görmek için bu kemanı kontrol et

Bunun nedeni, Vue DOM'u olarak güncelledi, Twokontrolü tarayıcıya verdi. Tarayıcı görüntülendi Two. Ardından, geri aramayı aradım. Vue, DOM'u olarak güncelledi Three. Hangi tarayıcı tekrar görüntülendi.

İle nextTick. Vue, DOM'u Two. Geri aramanı aradım. Vue, DOM'u olarak güncelledi Three. Daha sonra kontrolü tarayıcıya verdi. Ve tarayıcı görüntülendi Three.

Umarım açıktı.

Vue'nun bunu nasıl uyguladığını anlamak için, Olay Döngüsü ve mikro görevler kavramını anlamanız gerekir .

Bu kavramları netleştirdikten sonra (er), nextTick için kaynak kodunu kontrol edin .


4
Anlayamadığım bir şey, "veriyi günceller" dediğinizde, ex: ile yapılan güncellemeden this.name = 'foo'mi bahsediyorsunuz yoksa sayfada html öğelerinin enjeksiyonundan mı bahsediyorsunuz?
hidar

1
Bu sorunun geçmişinde "vue verileri günceller" dediği hiçbir yerde görmüyorum ... "Verilere dayalı olarak Vue DOM güncelliyor" diyor. Bu, verileri this.name = 'foo'vue aracılığıyla ayarladığınızda , yapılandırdığınız şablona ve işlevlere dayalı olarak verilerde yapılan değişiklikleri yansıtmak için belge nesne modelini günceller.
ADJenks

31

İçerik alınmıştır tarafından Adria Fontcuberta

Vue belgeleri diyor ki:

Vue.nextTick ([geri arama, içerik])

Sonraki DOM güncelleme döngüsünden sonra yürütülecek geri aramayı erteleyin. DOM güncellemesini beklemek için bazı verileri değiştirdikten hemen sonra kullanın.

Hmm ..., ilk başta korkutucu geliyorsa endişelenme, bunu olabildiğince basit bir şekilde açıklamaya çalışacağım. Ama önce bilmeniz gereken 2 şey var:

  1. Kullanımı nadirdir. Şu gümüş sihirli kartlardan biri gibi. Birkaç Vueuygulama yazdım ve nextTick () ile bir veya iki kez karşılaştım.

  2. Bazı gerçek kullanım durumlarını gördükten sonra anlamak daha kolay. Fikri anladıktan sonra korku kaybolacak ve kemerinizin altında kullanışlı bir aletiniz olacak.

O zaman gidelim.

$ NextTick'i Anlamak

Biz programcıyız, değil mi? Tanımı .nextTick()parça parça çevirmek için sevgili böl ve yönet yaklaşımımızı kullanacağız . Şununla başlar:

Geri aramayı erteleyin

Tamam, şimdi geri aramayı kabul ettiğini biliyoruz. Yani şuna benziyor:

Vue.nextTick(function () {
  // do something cool
});

Harika. Bu geri arama ertelenir (bu, binyıllar gecikti diyor) şu tarihe kadar

sonraki DOM güncelleme döngüsü.

Tamam. Vue'nun DOM güncellemelerini eşzamansız olarak gerçekleştirdiğini biliyoruz . Bu güncellemeleri, uygulanması gerekene kadar "saklamanın" bir yolunu sunar. Bir güncelleme sırası oluşturur ve gerektiğinde onu temizler. Ardından DOM "yamalanır" ve en son sürümüne güncellenir.

Ne?

Tekrar deneyeyim: Bileşeninizin, this.potatoAmount = 3.Vue'nun bileşeni (ve dolayısıyla DOM'u) otomatik olarak yeniden oluşturmayacağı gibi gerçekten gerekli ve akıllı bir şey yaptığını hayal edin . Gerekli değişikliği sıraya koyacaktır. Ardından, bir sonraki "onay" da (saatteki gibi), kuyruk temizlenir ve güncelleme uygulanır. Tada!

Tamam! Bu nedenle , veriler ayarlandıktan ve DOM güncellendikten hemen sonranextTick() yürütülen bir geri arama işlevini iletmek için kullanabileceğimizi biliyoruz .

Daha önce söylediğim gibi… o kadar sık ​​değil. Vue, React ve diğerini Google'dan yönlendiren ve bahsetmeyeceğim "veri akışı" yaklaşımı çoğu zaman bunu gereksiz kılıyor. Yine de, bazen DOM'da bazı öğelerin görünmesini / kaybolmasını / değiştirilmesini beklememiz gerekir. Bu, nextTick'in kullanışlı olduğu zamandır.

DOM güncellemesini beklemek için bazı verileri değiştirdikten hemen sonra kullanın.

Kesinlikle! Bu, Vue belgelerinin bize sağladığı son tanımdır. Geri aramamızın içinde, DOM, "en güncel" sürümüyle etkileşim kurabilmemiz için güncellendi.

Kanıtla

Tamam tamam. Konsolu görün ve verilerimizin değerinin yalnızca nextTick'in geri araması içinde güncellendiğini göreceksiniz:

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>

Bir kullanım durumu

İçin bazı yararlı kullanım durumları tanımlamaya çalışalım nextTick.

Bir bileşen monte edildiğinde bazı işlemler yapmanız gerektiğini düşünün. FAKAT! sadece bileşen değil. Ayrıca, tüm alt öğeleri eklenene ve DOM'da kullanılabilir olana kadar beklemeniz gerekir. Lanet olsun! Takılı kancamız, bileşen ağacının tamamının işleyeceğini garanti etmez.

Keşke bir sonraki DOM güncelleme döngüsünü bekleyecek bir aracımız olsaydı…

Hahaa:

mounted() {
  this.$nextTick(() => {
    // The whole view is rendered, so I can safely access or query
    // the DOM. ¯\_(ツ)_/¯
  })
}

Kısaca

So:, nextTickveriler ayarlandıktan ve DOM güncellendikten sonra bir işlevi yürütmenin rahat bir yoludur.

DOM'u beklemeniz gerekiyor, belki biraz dönüşüm yapmanız gerektiğinden veya harici bir kitaplığın içeriğini yüklemesini beklemeniz gerektiğinden mi? Ardından nextTick'i kullanın.

Bazı kişiler, verinin güncellendiğinden emin olmanın bir yolu olarak birim testlerinde nextTick'i de kullanır. Bu şekilde, bileşenin "güncellenmiş sürümünü" test edebilirler.

Vue.nextTick () veya vm. $ NextTick ()?

Merak etmeyin. Her ikisi de (neredeyse) aynı. Vue.nextTick()küresel API yöntemini ifade ederken vm.$nextTick(), bir örnek yöntemidir. Tek fark, vm.$nextTickikinci parametre olarak bir bağlamı kabul etmemesidir. Her zaman bağlıdır this(örneğin kendisi olarak da bilinir).

Son bir serinlik parçası

Bunun a nextTickdöndürdüğüne dikkat edin Promise, böylece async/awaitörneği tam anlamıyla kullanabilir ve iyileştirebiliriz:

async mounted () {
    this.message = 'updated'
    console.log(this.$el.textContent) // 'not updated'
    await this.$nextTick()
    console.log(this.$el.textContent) // 'updated'
}

4
Orijinal Yazarı ve bağlantıyı "sizin" açıklamanızın üstüne eklemeniz yeterlidir.
Renan Cidale

1
Ne harika bir açıklama! Zamanınız ve emeğiniz için çok teşekkür ederim.
Muaath Alhaddad

Lanet olsun, tüm orta yazıyı kopyaladın. Olumsuz oy verildi.
Alexander Kim

Geliştiriciler Google StackOverflowsonuçlarında cevabı aradığında genellikle ilk sonuçlar, SO cevaplar için gidilecek fiili yerdir, ancak internette arama sonuçlarında görünmeyebilecek birçok iyi kaynak vardır. Bu yüzden bu cevap için neredeyse yarım saat harcadım, bu sadece sizin belirttiğiniz gibi kopyalama değil, yazarın başından beri kredisi var. Gönderiyi beğenmediyseniz, sorun değil. Ama başkalarının işine saygı
duymalısın

1
Hahaha İnsanlar nextTick'in nasıl çalıştığını anladıkça (ve bir backlink zarar vermez!);)
afontcu

16

Sonraki Kene, temelde, reaktif bir özellikte (veriler) bazı değişiklikler yaptığınızda vue bileşeni yeniden oluşturduktan sonra bazı kodları çalıştırmanıza izin verir.

// 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.
})

Vue.js Belgelerinden:

Sonraki DOM güncelleme döngüsünden sonra yürütülecek geri aramayı erteleyin. DOM güncellemesini beklemek için bazı verileri değiştirdikten hemen sonra kullanın.

Bununla ilgili daha fazlasını buradan okuyun .


2
nasıl güncelle? bu benim üstlenmediğim şey. Ben vm.msg güncellemek eğer yeni bir metin 'olduğu için daha sonra dom zaten güncellenir' Merhaba" .. bu yüzden tekrar güncelleyebilirsiniz nasıl bir örnek lütfen sayesinde bir keman yayınlayabilir??
hidar

tamam, cevabı düzenleyeceğim ve daha fazla açıklamaya çalışacağım.
Daksh Miglani

@hidar, birden fazla güncelleme yapmanız gerektiğinde, ancak birbirinizi farklı dom döngülerinde açıkça oluşturmak istediğiniz durumlarda kullanabilirsiniz
Daksh Miglani

DOM'u kendi başına güncellemenize izin vermek için değil, Vue tarafından yapılan değişikliklerden etkilendikten / değiştirildikten sonra onunla herhangi bir şey (güncelleme, bilgi okuma, vb.) Yapmanız için (çünkü reaktif bir özellik değerini değiştirmişsinizdir) , vb).
zenw0lf

Bu, daha basit hale getirmek için bir örnekti.
Daksh Miglani

7

NextTick ve setTimeout kullanımı arasındaki farkla ilgili Pranshat'ın cevabını daha açık hale getirmek için, onun kemanını çatalladım: burada

mounted() {    
  this.one = "One";
 
  setTimeout(() => {
    this.two = "Two"
  }, 0);
  
  //this.$nextTick(()=>{
  //this.two = "Two"
  //})}

Keman içinde, setTimeOut kullanılırken, değişiklik uyarlanmadan önce bileşen monte edildiğinde ilk verilerin çok kısa bir süre yanıp söndüğünü görebilirsiniz. Oysa nextTick kullanılırken, tarayıcıya sunulmadan önce veriler ele geçirilir, değiştirilir. Böylelikle tarayıcı, eski verileri bile bilmeden güncellenmiş verileri gösterir. Umarım bu iki kavramı tek seferde temizler.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.