- Pelajari
-
Ekosistem
Pertolongan
Alat
Pustaka Inti
Berita
Daftar Sumber Daya
- Tim
- Dukung Vue
- Terjemahan
Petunjuk
Esensial
- Instalasi
- Perkenalan
- Vue Instance
- Sintaks Templat
- Properti Penghitung (Computed) dan Pengamat (Watchers)
- Kelas and Binding Gaya
- Rendering Bersyarat
- Me-render Daftar
- Penanganan Event
- Form Input Bindings
- Komponen Dasar
Komponen secara mendalam
- Registrasi Komponen
- Props
- Custom Events
- Slot
- Komponen yang Dinamis & Async
- Menangani Kasus Langka
Transisi & Animasi
- Transisi Masuk/Keluar & Daftar Transisi
- Transisi State
Kebergunaan & Komposisi
- Mixins
- Direktif Kustom
- Fungsi Render & JSX
- Plugin
- Filter
Peralatan
- Komponen Berkas Tunggal
- Unit Testing
- Dukungan TypeScript
- Penempatan Produksi
Peningkatan
- Routing
- Pengelolaan State
- Rendering di Sisi Server (SSR)
Internal
- Reaktivitas Secara Mendalam
Migrasi
- Migrasi dari Vue 1.x
- Migrasi dari Vuex 0.6.x ke 1.0
Meta
- Perbandingan dengan Kerangka Kerja yang Lain
- Gabung Komunitas Vue.js!
- Tim Inti Vuejs
Reaktivitas Secara Mendalam
Sakarang waktunya untuk pemahaman secara mendalam! Salah satu fitur pembeda Vue adalah sistem reaktivitas yang tidak menyulitkan. Model hanyalah objek JavaScript biasa. Saat Anda memodifikasinya, tampilan diperbarui. Itu membuat manajemen state menjadi sederhana dan intuitif, tetapi juga penting untuk memahami cara kerjanya untuk menghindari beberapa kesalahan umum. Pada bagian ini, kita akan menggali beberapa detail sistem reaktivitas Vue pada tingkat yang lebih rendah.
Bagaimana Perubahan Dilacak
Saat Anda mengoper objek JavaScript biasa ke instance Vue sebagai opsi data
, Vue akan menelusuri semua propertinya dan mengonversinya menjadi getter/setters menggunakan Object.defineProperty. Ini adalah fitur ES5 dan un-shimmable, itulah sebabnya Vue tidak mendukung IE8 dan di bawahnya.
Getter/setters tidak terlihat oleh pengguna, tapi memungkinkan Vue untuk melakukan pelacakan dependency dan pemberitahuan perubahan saat properti diakses atau diubah. Satu kekurangannya adalah bahwa format getter/setters konsol peramban berbeda ketika objek data yang dikonversi dicatat, jadi Anda mungkin ingin memasang vue-devtools untuk antarmuka yang lebih ramah inspeksi.
Setiap instance komponen memiliki pengamat yang terhubung, yang merekam properti apa pun yang “disentuh” selama komponen di-render sebagai dependencies. Kemudian ketika setter dependencies dipicu, ia memberi tahu pengamat, yang pada gilirannya menyebabkan komponen untuk me-render ulang.
Kekurangan Deteksi Pengubahan
Karena keterbatasan JavaScript modern (dan ditinggalkannya Object.observe
), Vue tidak dapat mendeteksi penambahan atau penghapusan properti. Karena Vue melakukan proses konversi getter/setter selama inisialisasi instance, properti harus ada di objek data
agar Vue dapat mengonversinya dan membuatnya reaktif. Sebagain contoh:
var vm = new Vue({
data: {
a: 1
}
})
// `vm.a` sekarang reaktif
vm.b = 2
// `vm.b` TIDAK reaktif
Vue tidak mengizinkan penambahkan properti reaktif yang baru secara dinamis pada tingkat root ke instance yang sudah dibuat. Namun, dimungkinkan untuk menambahkan properti reaktif ke objek bersarang menggunakan metode Vue.set(object, key, value)
Vue.set(vm.someObject, 'b', 2)
Anda juga dapat menggunakan metode instance vm. $ Set
, yang merupakan alias untuk globalVue.set
:
this.$set(this.someObject, 'b', 2)
Terkadang Anda mungkin ingin menetapkan sejumlah properti ke objek yang ada, sebagai contoh menggunakan Object.assign()
atau _.extend()
. Namun, properti baru yang ditambahkan ke objek tidak akan memicu perubahan. Dalam kasus seperti itu, buat objek baru dengan properti dari objek asli dan objek baru:
// dari pada `Object.assign(this.someObject, { a: 1, b: 2 })`
this.someObject = Object.assign({}, this.someObject, { a: 1, b: 2 })
Ada juga beberapa kekurangan terkait array, yang telah dibahas sebelumnya di daftar bagian rendering.
Deklarasi Properti Reaktif
Karena Vue tidak memungkinkan menambahkan properti reaktif tingkat root secara dinamis, Anda harus menginisialisasi instance Vue dengan mendeklarasikan semua properti data reaktif tingkat root terlebih dahulu, bahkan dengan nilai kosong:
var vm = new Vue({
data: {
// deklarasi `message` dengan nilai kosong
message: ''
},
template: '<div>{{ message }}</div>'
})
// set `message` nanti
vm.message = 'Hello!'
Jika Anda tidak mendeklarasikan message
dalam opsi data, Vue akan memperingatkan Anda bahwa fungsi render sedang mencoba mengakses properti yang tidak ada.
Ada alasan teknis di balik pembatasan ini - yaitu menghilangkan kelompok kasus khusus dalam sistem pelacakan-dependency, dan juga membuat instance Vue lebih baik dengan sistem pengecekan tipe. Tapi ada juga pertimbangan penting dalam hal pemeliharaan kode: objek data
seperti skema untuk state komponen Anda. Mendeklarasikan semua properti reaktif terlebih dahulu membuat kode komponen lebih mudah dipahami ketika ditinjau kembali nanti atau dibaca oleh pengembang lain.
Pembaruan Antrian Async
Jika Anda belum menyadarinya, Vue melakukan pembaruan DOM asynchronously. Setiap kali perubahan data diamati, akan membuka antrian dan buffer semua perubahan data yang terjadi di event loop yang sama. Jika pengamat yang sama dipicu beberapa kali, akan dimasukan ke antrian hanya sekali. Menghilangkan duplikasi buffered ini penting dalam menghindari perhitungan yang tidak perlu dan manipulasi DOM. Kemudian pada “tick” event loop berikutnya, Vue membersihkan antrian dan melakukan pekerjaan yang sebenarnya (duplikasi sudah dihilangkan). Vue secara internal mencoba Promise.then
danMessageChannel
bawaan untuk antrian yang asynchronous dan kembali ke setTimeout (fn, 0)
jika peramban belum mendukung.
Sebagai contoh, ketika Anda menetapkan vm.someData = 'new value'
, komponen tidak akan segera me-render ulang. komponen akan memperbarui dalam “tick” berikutnya, ketika antrian dibersihkan. Pada umumnya kita tidak perlu peduli tentang ini, tetapi bisa rumit ketika Anda ingin melakukan sesuatu yang tergantung pada state DOM pasca pembaruan. Meskipun Vue.js umumnya mendorong pengembang untuk berpikir dengan cara “data-driven” dan menghindari menyentuh DOM secara langsung, kadang-kadang mungkin perlu Anda perlu untuk melakukannya. Untuk menunggu sampai Vue.js selesai memperbarui DOM setelah perubahan data, Anda bisa menggunakan Vue.nextTick(callback)
segera setelah data diubah. Callback akan dipanggil setelah DOM diperbarui. Sebagai contoh:
<div id="example">{{ message }}</div>
var vm = new Vue({
el: '#example',
data: {
message: '123'
}
})
vm.message = 'new message' // ubah data
vm.$el.textContent === 'new message' // salah
Vue.nextTick(function () {
vm.$el.textContent === 'new message' // benar
})
Ada juga metode instance vm. $ NextTick ()
, yang sangat berguna di dalam komponen, karena tidak memerlukan global Vue
dan konteks this
pada callback akan secara otomatis bound ke instance Vue saat ini:
Vue.component('example', {
template: '<span>{{ message }}</span>',
data: function () {
return {
message: 'not updated'
}
},
methods: {
updateMessage: function () {
this.message = 'updated'
console.log(this.$el.textContent) // => 'tidak diperbarui'
this.$nextTick(function () {
console.log(this.$el.textContent) // => 'diperbarui'
})
}
}
})
Sejak nilai kembalian dari $nextTick()
adalah promise, Anda dapat mencapai hal yang sama diatas dengan sintaksis ES2016 async/await syntax: yang baru
methods: {
updateMessage: async function () {
this.message = 'updated'
console.log(this.$el.textContent) // => 'tidak diperbaharui'
await this.$nextTick()
console.log(this.$el.textContent) // => 'diperbarui'
}
}