Saya memiliki sebuah array bernama people
yang berisi objek sebagai berikut:
Sebelum
[
{id: 0, name: 'Bob', age: 27},
{id: 1, name: 'Frank', age: 32},
{id: 2, name: 'Joe', age: 38}
]
Itu bisa berubah:
Setelah
[
{id: 0, name: 'Bob', age: 27},
{id: 1, name: 'Frank', age: 33},
{id: 2, name: 'Joe', age: 38}
]
Perhatikan bahwa Frank baru saja berusia 33 tahun.
Saya memiliki aplikasi di mana saya mencoba untuk menonton array orang dan ketika salah satu nilai berubah, maka catat perubahannya:
<style>
input {
display: block;
}
</style>
<div id="app">
<input type="text" v-for="(person, index) in people" v-model="people[index].age" />
</div>
<script>
new Vue({
el: '#app',
data: {
people: [
{id: 0, name: 'Bob', age: 27},
{id: 1, name: 'Frank', age: 32},
{id: 2, name: 'Joe', age: 38}
]
},
watch: {
people: {
handler: function (val, oldVal) {
// Return the object that changed
var changed = val.filter( function( p, idx ) {
return Object.keys(p).some( function( prop ) {
return p[prop] !== oldVal[idx][prop];
})
})
// Log it
console.log(changed)
},
deep: true
}
}
})
</script>
Saya mendasarkan ini pada pertanyaan yang saya tanyakan kemarin tentang perbandingan array dan memilih jawaban kerja tercepat.
Jadi, pada titik ini saya berharap untuk melihat hasil dari: { id: 1, name: 'Frank', age: 33 }
Tetapi yang saya dapatkan kembali di konsol adalah (mengingat saya memilikinya di sebuah komponen):
[Vue warn]: Error in watcher "people"
(found in anonymous component - use the "name" option for better debugging messages.)
Dan pada codepen yang saya buat , hasilnya berupa array kosong dan bukan objek yang diubah yang berubah seperti yang saya harapkan.
Jika ada yang bisa menyarankan mengapa ini terjadi atau di mana saya salah di sini maka itu akan sangat dihargai, terima kasih banyak!
sumber
Saya telah mengubah penerapannya untuk menyelesaikan masalah Anda, saya membuat objek untuk melacak perubahan lama dan membandingkannya dengan itu. Anda dapat menggunakannya untuk menyelesaikan masalah Anda.
Di sini saya membuat metode, di mana nilai lama akan disimpan dalam variabel terpisah dan, yang kemudian akan digunakan di jam tangan.
Lihat codepen yang diperbarui
sumber
vm.$data
, terima kasih!Ini adalah perilaku yang terdefinisi dengan baik. Anda tidak bisa mendapatkan nilai lama untuk objek yang bermutasi . Itu karena kedua
newVal
danoldVal
merujuk pada objek yang sama. Vue tidak akan menyimpan salinan lama dari objek yang Anda mutasi.Seandainya Anda mengganti objek itu dengan yang lain, Vue akan memberi Anda referensi yang benar.
Baca
Note
bagian di dokumen. (vm.$watch
)Lebih lanjut tentang ini di sini dan di sini .
sumber
Inilah yang saya gunakan untuk mengamati sebuah objek. Persyaratan saya adalah memperhatikan bidang anak objek.
sumber
Solusi komponen dan solusi deep-clone memiliki kelebihan, tetapi juga memiliki masalah:
Terkadang Anda ingin melacak perubahan dalam data abstrak - membuat komponen di sekitar data itu tidak selalu masuk akal.
Mengkloning seluruh struktur data Anda setiap kali Anda membuat perubahan bisa sangat mahal.
Saya pikir ada cara yang lebih baik. Jika Anda ingin menonton semua item dalam daftar dan mengetahui item mana dalam daftar yang berubah, Anda dapat mengatur pengamat khusus pada setiap item secara terpisah, seperti:
Dengan struktur ini,
handleChange()
akan menerima item daftar tertentu yang diubah - dari sana Anda dapat melakukan penanganan yang Anda suka.Saya juga telah mendokumentasikan skenario yang lebih kompleks di sini , jika Anda menambahkan / menghapus item ke daftar Anda (daripada hanya memanipulasi item yang sudah ada).
sumber