Apa itu nextTick atau apa fungsinya di VueJs

108

Saya membaca dokumennya, tapi saya tidak bisa memahaminya. Saya tahu data apa, dihitung, tonton, metode lakukan tetapi untuk apa nextTick()digunakan dalam vuejs?

hidar
sumber
18
Konsep utama yang harus dipahami adalah bahwa DOM diperbarui secara asinkron . Saat Anda mengubah nilai di Vue, perubahan tersebut tidak langsung dirender ke DOM. Sebagai gantinya, Vue mengantrekan pembaruan DOM dan kemudian, pada pengatur waktu, memperbarui DOM. Biasanya, ini terjadi sangat cepat sehingga tidak membuat perbedaan, tetapi, terkadang, Anda perlu memperbarui DOM yang telah dirender setelah Vue merendernya, yang tidak dapat segera Anda lakukan dalam suatu metode karena pembaruan belum terjadi. namun. Dalam kasus tersebut, Anda akan menggunakan nextTick. Didokumentasikan di sini .
Bert
Melengkapi apa yang dikatakan @Bert di https://stackoverflow.com/q/47634258/9979046 di atas, nextTick () akan digunakan dalam Pengujian Unit, saat Anda perlu memeriksa apakah ada elemen di DOM (HTML), misalnya, jika Anda mendapatkan beberapa informasi tentang permintaan Axios.
Oscar Alencar

Jawaban:

141

nextTick memungkinkan Anda melakukan sesuatu setelah Anda mengubah data dan VueJS telah memperbarui DOM berdasarkan perubahan data Anda, tetapi sebelum browser membuat perubahan tersebut pada halaman.

Biasanya, pengembang menggunakan fungsi JavaScript asli setTimeout untuk mencapai perilaku serupa. Namun, menggunakan setTimeoutmelepaskan kontrol ke browser sebelum memberikan kontrol kembali kepada Anda melalui panggilan balik Anda.

Misalnya, Anda mengubah beberapa data. Vue memperbarui DOM berdasarkan data. Ingatlah bahwa perubahan DOM belum ditampilkan ke layar oleh browser. Jika Anda dulu nextTick, callback Anda dipanggil sekarang. Kemudian, browser memperbarui halaman. Jika Anda dulu setTimeout, panggilan balik Anda hanya akan dipanggil sekarang.

Anda dapat memvisualisasikan perilaku ini dengan membuat komponen kecil seperti berikut:

<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>

Jalankan server lokal Anda. Anda akan melihat pesan Threetersebut ditampilkan.

Sekarang, ganti this.$nextTickdengansetTimeout

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

Muat ulang browser. Anda akan melihat Two, sebelum Anda melihat Three.

Periksa biola ini untuk melihatnya langsung

Itu karena, Vue memperbarui DOM menjadi Two, memberikan kendali pada browser. Browser ditampilkan Two. Kemudian, panggil panggilan balik Anda. Vue memperbarui DOM menjadi Three. Yang browser ditampilkan lagi.

Dengan nextTick. Vue memilih DOM ke Two. Menelepon panggilan balik Anda. Vue memperbarui DOM menjadi Three. Kemudian berikan kendali pada browser. Dan, browser ditampilkan Three.

Semoga sudah jelas.

Untuk memahami bagaimana Vue mengimplementasikan ini, Anda perlu memahami konsep Event Loop dan microtasks .

Setelah Anda memiliki konsep yang jelas (er), periksa kode sumber untuk klik berikutnya .

Prashant
sumber
4
Satu hal yang tidak saya mengerti adalah ketika Anda mengatakan, "vue update data", apakah Anda mengacu pada update made with ex: this.name = 'foo'atau apakah Anda mengacu pada injeksi elemen html di halaman?
hidar
Saya tidak melihat di mana pun dalam riwayat pertanyaan ini di mana dia mengatakan "vue memperbarui data" ... Dia mengatakan "Vue memperbarui DOM berdasarkan data". Yang berarti bahwa ketika Anda menyetel data melalui this.name = 'foo'vue memperbarui model objek dokumen untuk mencerminkan perubahan yang dibuat pada data berdasarkan template dan fungsi yang Anda konfigurasikan.
ADJenks
25

Konten tersebut telah diambil dari By Adrià Fontcuberta

Dokumentasi Vue mengatakan:

Vue.nextTick ([callback, konteks])

Tunda callback untuk dijalankan setelah siklus pembaruan DOM berikutnya. Gunakan segera setelah Anda mengubah beberapa data untuk menunggu pembaruan DOM.

Hmm ..., jika terasa mengintimidasi pada awalnya, jangan khawatir saya akan mencoba menjelaskannya sesederhana mungkin. Tapi pertama-tama ada 2 hal yang harus Anda ketahui:

  1. Penggunaannya tidak umum. Seperti salah satu dari kartu ajaib perak itu. Saya telah menulis beberapa Vueaplikasi dan menemukan nextTick () sekali atau dua kali.

  2. Lebih mudah untuk dipahami setelah Anda melihat beberapa kasus penggunaan nyata. Setelah Anda mendapatkan ide, rasa takut akan hilang, dan Anda akan memiliki alat yang berguna di bawah ikat pinggang Anda.

Mari kita lakukan.

Memahami $ nextTick

Kami adalah programmer, bukan? Kami akan menggunakan pendekatan divide and conquer tercinta kami untuk mencoba menerjemahkan deskripsi .nextTick()sedikit demi sedikit. Ini dimulai dengan:

Tunda panggilan balik

Oke, sekarang kita tahu itu menerima panggilan balik. Jadi terlihat seperti ini:

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

Bagus. Callback ini ditunda (begitulah istilah milenial tertunda) hingga…

siklus pembaruan DOM berikutnya.

Baik. Kami tahu bahwa Vue melakukan pembaruan DOM secara asynchronous . Ini menampilkan cara untuk menjaga pembaruan ini "disimpan" hingga perlu menerapkannya. Ini membuat antrian pembaruan dan membersihkannya saat diperlukan. Kemudian, DOM "ditambal" dan diperbarui ke versi terbarunya.

Apa?

Izinkan saya mencoba lagi: Bayangkan komponen Anda melakukan sesuatu yang sangat penting dan cerdas seperti this.potatoAmount = 3.Vue tidak akan merender ulang komponen (dan juga DOM) secara otomatis. Ini akan mengantri modifikasi yang diperlukan. Kemudian, di "centang" berikutnya (seperti pada jam), antrean dihapus, dan pembaruan diterapkan. Tada!

Baik! Jadi kita tahu bahwa kita bisa menggunakan nextTick()untuk melewatkan fungsi panggilan balik yang dijalankan tepat setelah data disetel dan DOM telah diperbarui.

Seperti yang saya katakan sebelumnya… tidak sesering itu. Pendekatan "aliran data" yang mendorong Vue, React, dan yang lainnya dari Google, yang tidak akan saya sebutkan, membuatnya tidak perlu hampir sepanjang waktu. Namun, terkadang kita perlu menunggu beberapa elemen muncul / menghilang / dimodifikasi di DOM. Ini adalah saat nextTick berguna.

Gunakan segera setelah Anda mengubah beberapa data untuk menunggu pembaruan DOM.

Persis! Ini adalah bagian terakhir dari definisi yang diberikan oleh Vue docs kepada kami. Di dalam callback kami, DOM telah diperbarui sehingga kami dapat berinteraksi dengan versi "terbaru".

Buktikan itu

Oke oke. Lihat konsolnya, dan Anda akan melihat bahwa nilai data kami diperbarui hanya di dalam callback 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>

Kasus penggunaan

Mari kita coba untuk mendefinisikan beberapa kasus penggunaan yang berguna untuk nextTick.

Bayangkan Anda perlu melakukan beberapa tindakan saat komponen dipasang. TAPI! bukan hanya komponennya. Anda juga perlu menunggu sampai semua turunannya dipasang dan tersedia di DOM. Sial! Kait terpasang kami tidak menjamin bahwa seluruh pohon komponen merender.

Andai saja kami memiliki alat untuk menunggu siklus pembaruan DOM berikutnya ...

Hahaa:

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

Pendeknya

Jadi: nextTickadalah cara yang nyaman untuk menjalankan suatu fungsi setelah datanya disetel, dan DOM telah diperbarui.

Anda perlu menunggu DOM, mungkin karena Anda perlu melakukan beberapa transformasi atau Anda perlu menunggu perpustakaan eksternal memuat barang-barangnya? Kemudian gunakan nextTick.

Beberapa orang juga menggunakan nextTick dalam pengujian unit mereka sebagai cara untuk memastikan bahwa data telah diperbarui. Dengan cara ini, mereka dapat menguji "versi yang diperbarui" dari komponen tersebut.

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

Jangan khawatir. Keduanya (hampir) sama. Vue.nextTick()mengacu pada metode API global, sedangkan vm.$nextTick()metode instance. Satu-satunya perbedaan adalah vm.$nextTicktidak menerima konteks sebagai parameter kedua. Itu selalu terikat ke this(juga dikenal sebagai instance itu sendiri).

Bagian terakhir dari kesejukan

Perhatikan bahwa nextTickmengembalikan a Promise, jadi kita bisa sepenuhnya keren async/awaitdan meningkatkan contoh:

async mounted () {
    this.message = 'updated'
    console.log(this.$el.textContent) // 'not updated'
    await this.$nextTick()
    console.log(this.$el.textContent) // 'updated'
}
Humoyun Ahmad
sumber
2
Cukup tambahkan Penulis asli dan tautannya, di atas penjelasan "Anda".
Renan Cidale
1
Sungguh penjelasan yang luar biasa! Terima kasih banyak atas waktu dan tenaga Anda.
Muaath Alhaddad
16

Next Tick pada dasarnya memungkinkan Anda untuk menjalankan beberapa kode, setelah vue telah merender ulang komponen tersebut ketika Anda telah membuat beberapa perubahan pada properti reaktif (data).

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

Dari Dokumentasi Vue.js:

Tunda callback untuk dijalankan setelah siklus pembaruan DOM berikutnya. Gunakan segera setelah Anda mengubah beberapa data untuk menunggu pembaruan DOM.

Baca lebih lanjut tentang itu, di sini .

Daksh Miglani
sumber
2
perbarui bagaimana? inilah yang tidak saya mengerti. jika saya memperbarui vm.msg maka dom sudah diperbarui karena ada teks baru '' halo ".. jadi bagaimana saya bisa memperbaruinya lagi? dapatkah Anda memposting biola dengan contoh? terima kasih
hidar
oke, saya akan mengedit jawabannya dan saya akan mencoba menjelaskannya lebih lanjut.
Daksh Miglani
@hidar Anda dapat menggunakannya dalam situasi ketika Anda harus melakukan banyak pembaruan, tetapi Anda ingin secara eksplisit merender satu sama lain pada siklus dom yang berbeda
Daksh Miglani
Ini bukan untuk mengizinkan Anda memperbarui DOM itu sendiri, tetapi untuk melakukan apa pun dengannya (baik itu memperbarui, membaca info darinya, dll) setelah terpengaruh / dimodifikasi oleh perubahan yang dilakukan oleh Vue (karena Anda mengubah nilai properti reaktif , dll).
zenw0lf
Itu adalah contoh untuk membuatnya lebih sederhana.
Daksh Miglani
7

Untuk membuat jawaban Pransitu tentang perbedaan antara menggunakan nextTick dan setTimeout, lebih eksplisit, saya telah membagi biolanya: di sini

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

Anda dapat melihat di biola bahwa saat menggunakan setTimeOut, data awal berkedip sangat singkat setelah komponen dipasang sebelum mengadaptasi perubahan. Padahal, saat menggunakan nextTick, data dibajak, diubah, sebelum dirender ke browser. Jadi, browser menampilkan data yang diperbarui bahkan tanpa sepengetahuan yang lama. Harapan yang menyelesaikan dua konsep dalam satu gerakan.

Wale
sumber