Saya mulai https://laracasts.com/series/learning-vue-step-by-step series. Saya berhenti pada pelajaran Vue, Laravel, dan AJAX dengan kesalahan ini:
vue.js: 2574 [Peringatan Vue]: Hindari memutasi prop secara langsung karena nilai akan ditimpa setiap kali komponen induk dirender ulang. Alih-alih, gunakan data atau properti yang dihitung berdasarkan nilai prop. Prop sedang dimutasi: "daftar" (ditemukan dalam komponen)
Saya memiliki kode ini di main.js
Vue.component('task', {
template: '#task-template',
props: ['list'],
created() {
this.list = JSON.parse(this.list);
}
});
new Vue({
el: '.container'
})
Saya tahu bahwa masalahnya sedang dibuat () ketika saya menimpa daftar prop, tapi saya seorang pemula di Vue, jadi saya benar-benar tidak tahu cara memperbaikinya. Adakah yang tahu bagaimana cara (dan tolong jelaskan alasannya) untuk memperbaikinya?
javascript
vue.js
vuejs2
Dariusz Chowański
sumber
sumber
Jawaban:
Ini ada hubungannya dengan fakta bahwa bermutasi prop secara lokal dianggap sebagai anti-pola dalam Vue 2
Apa yang harus Anda lakukan sekarang, jika Anda ingin bermutasi prop secara lokal , adalah mendeklarasikan bidang di Anda
data
yang menggunakanprops
nilai sebagai nilai awal dan kemudian bermutasi salinan:Anda dapat membaca lebih lanjut tentang ini di panduan resmi Vue.js
Catatan 1: Harap dicatat bahwa Anda tidak boleh menggunakan nama yang sama untuk Anda
prop
dandata
, yaitu:Catatan 2: Karena saya merasa ada beberapa kebingungan tentang
props
dan reaktivitas , saya sarankan Anda untuk melihat pada utas inisumber
Pola Vue
props
turun danevents
naik. Kedengarannya sederhana, tetapi mudah dilupakan saat menulis komponen khusus.Pada Vue 2.2.0 Anda dapat menggunakan model-v (dengan properti yang dihitung ). Saya telah menemukan kombinasi ini menciptakan antarmuka yang sederhana, bersih, dan konsisten antara komponen:
props
diteruskan ke komponen Anda tetap reaktif (yaitu, itu tidak dikloning juga tidak memerlukanwatch
fungsi untuk memperbarui salinan lokal ketika perubahan terdeteksi).Properti yang dikomputasi memungkinkan penyetel dan pengambil ditetapkan secara terpisah. Ini memungkinkan
Task
komponen untuk ditulis ulang sebagai berikut:The Model mendefinisikan properti yang
prop
berhubungan denganv-model
, dan yang acara akan dipancarkan pada perubahan. Anda kemudian dapat memanggil komponen ini dari induknya sebagai berikut:The
listLocal
properti dihitung menyediakan getter dan setter antarmuka yang sederhana dalam komponen (berpikir itu seperti berada variabel pribadi). Di dalam#task-template
Anda dapat membuatlistLocal
dan itu akan tetap reaktif (yaitu, jikaparentList
perubahan itu akan memperbaruiTask
komponen). Anda juga dapat bermutasilistLocal
dengan memanggil setter (mis.,this.listLocal = newList
) Dan itu akan memancarkan perubahan ke induk.Apa yang hebat tentang pola ini adalah Anda dapat beralih
listLocal
ke komponen anak dariTask
(menggunakanv-model
), dan perubahan dari komponen anak akan menyebar ke komponen tingkat atas.Misalnya, kita memiliki
EditTask
komponen terpisah untuk melakukan beberapa jenis modifikasi pada data tugas. Dengan menggunakanv-model
pola properti yang sama dan dikomputasi, kita dapat beralihlistLocal
ke komponen (menggunakanv-model
):Jika
EditTask
memancarkan perubahan dengan tepat akan memanggilset()
padalistLocal
dan dengan demikian menyebarkan acara ke tingkat atas. Demikian pula,EditTask
komponen juga bisa memanggil komponen anak lainnya (seperti elemen formulir) menggunakanv-model
.sumber
Vue hanya memperingatkan Anda: Anda mengubah penyangga dalam komponen, tetapi ketika komponen induk dirender kembali, "daftar" akan ditimpa dan Anda kehilangan semua perubahan Anda. Jadi berbahaya untuk melakukannya.
Gunakan properti yang dihitung sebagai gantinya:
sumber
Jika Anda menggunakan Lodash, Anda dapat mengkloning prop sebelum mengembalikannya. Pola ini bermanfaat jika Anda memodifikasi penyangga itu pada orang tua dan anak.
Katakanlah kita memiliki daftar prop pada kisi komponen .
Dalam Komponen Induk
Dalam Komponen Anak
sumber
Alat peraga turun, acara naik. Itu Pola Vue. Intinya adalah bahwa jika Anda mencoba untuk mengubah alat peraga yang lewat dari orangtua. Itu tidak akan berfungsi dan hanya akan ditimpa berulang kali oleh komponen induk. Komponen anak hanya dapat memancarkan suatu peristiwa untuk memberi tahu komponen induk untuk melakukan sth. Jika Anda tidak menyukai batasan ini, Anda dapat menggunakan VUEX (sebenarnya pola ini akan menyedot struktur komponen yang kompleks, Anda harus menggunakan VUEX!)
sumber
Anda tidak boleh mengubah nilai alat peraga dalam komponen anak. Jika Anda benar-benar perlu mengubahnya, Anda dapat menggunakannya
.sync
. Seperti ini<your-component :list.sync="list"></your-component>
sumber
Menurut VueJs 2.0, Anda tidak harus bermutasi prop di dalam komponen. Mereka hanya bermutasi oleh orang tua mereka. Karena itu, Anda harus mendefinisikan variabel dalam data dengan nama yang berbeda dan tetap memperbaruinya dengan menonton alat peraga yang sebenarnya. Jika prop daftar diubah oleh induk, Anda dapat menguraikannya dan menetapkannya ke mutableList. Ini solusi lengkapnya.
Ini menggunakan mutableList untuk membuat template Anda, sehingga Anda menyimpan prop daftar Anda aman di komponen.
sumber
jangan mengubah alat peraga secara langsung dalam komponen. jika Anda perlu mengubahnya setel properti baru seperti ini:
Dan ubah nilai listClone.
sumber
Jawabannya sederhana, Anda harus memecah mutasi prop langsung dengan menetapkan nilai ke beberapa variabel komponen lokal (bisa berupa properti data, dihitung dengan getter, setter, atau pengamat).
Inilah solusi sederhana menggunakan pengamat.
Ini yang saya gunakan untuk membuat komponen input data dan berfungsi dengan baik. Setiap data baru yang dikirim (model-v (ed)) dari induk akan diawasi oleh pengamat nilai dan ditugaskan ke variabel input dan setelah input diterima, kita dapat menangkap tindakan itu dan memancarkan input ke induk yang menyarankan bahwa data adalah input dari elemen form.
sumber
Saya menghadapi masalah ini juga. Peringatan hilang setelah saya menggunakan
$on
dan$emit
. Ini seperti penggunaan$on
dan$emit
direkomendasikan untuk mengirim data dari komponen anak ke komponen induk.sumber
Jika Anda ingin mengubah alat peraga - gunakan objek.
komponen:
sumber
Anda perlu menambahkan metode yang dihitung seperti ini
komponen.vue
sumber
aliran data satu arah, menurut https://vuejs.org/v2/guide/components.html , komponen mengikuti aliran data satu arah, semua alat peraga membentuk ikatan satu arah yang turun antara properti anak dan orang tua satu, ketika properti induk diperbarui, itu akan mengalir ke anak tetapi tidak sebaliknya, ini mencegah komponen anak dari secara tidak sengaja bermutasi pada orang tua, yang dapat membuat aliran data aplikasi Anda lebih sulit untuk dipahami.
Selain itu, setiap kali komponen induk diperbarui, semua alat peraga dalam komponen turunan akan disegarkan dengan nilai terbaru. Ini berarti Anda tidak boleh mencoba untuk memutasikan penyangga di dalam komponen anak. Jika Anda melakukannya .vue akan memperingatkan Anda di konsol.
Biasanya ada dua kasus di mana tergoda untuk bermutasi prop: Prop digunakan untuk memberikan nilai awal; komponen anak ingin menggunakannya sebagai properti data lokal sesudahnya. Prop disahkan sebagai nilai mentah yang perlu diubah. Jawaban yang tepat untuk kasus penggunaan ini adalah: Tentukan properti data lokal yang menggunakan nilai awal prop sebagai nilai awalnya:
Tetapkan properti yang dihitung yang dihitung dari nilai prop:
sumber
Alat peraga Vue.js tidak boleh dimutasi karena ini dianggap sebagai Anti-Pola di Vue.
Pendekatan yang perlu Anda ambil adalah membuat properti data pada komponen Anda yang mereferensikan properti prop asli daftar
Sekarang struktur daftar Anda yang diteruskan ke komponen direferensikan dan dimutasi melalui
data
properti komponen Anda :-)Jika Anda ingin melakukan lebih dari sekadar mengurai properti daftar Anda, gunakan
computed
properti komponen Vue . Ini memungkinkan Anda untuk membuat lebih banyak mutasi mendalam ke alat peraga Anda.Contoh di atas mem-parsing prop daftar Anda dan memfilternya hanya ke list-tems yang aktif , mencatatnya untuk schnitts dan cekikikan dan mengembalikannya.
catatan : keduanya
data
&computed
properti direferensikan dalam template misalnya samaSangat mudah untuk berpikir bahwa sebuah
computed
properti (menjadi metode) perlu disebut ... tidaksumber
Mungkin ini akan memenuhi kebutuhan Anda.
sumber
Menambah jawaban terbaik,
Mengatur alat peraga oleh array dimaksudkan untuk dev / prototyping, dalam produksi pastikan untuk menetapkan jenis alat peraga ( https://vuejs.org/v2/guide/components-props.html ) dan tetapkan nilai default jika prop tidak memiliki telah diisi oleh orang tua, seperti itu.
Dengan cara ini Anda setidaknya mendapatkan objek kosong
mutableList
daripada kesalahan JSON.parse jika tidak terdefinisi.sumber
Vue.js menganggap ini sebagai anti-pola. Misalnya, mendeklarasikan dan mengatur beberapa alat peraga seperti
Jadi untuk mengatasi masalah ini, Anda harus mengambil nilai dari properti ke data atau properti yang dihitung dari instance Vue, seperti ini:
Ini pasti akan berhasil.
sumber
Selain hal di atas, untuk orang lain yang memiliki masalah berikut:
"Jika nilai properti tidak diperlukan dan dengan demikian tidak selalu dikembalikan, data yang dikirimkan akan kembali
undefined
(bukan kosong)". Yang bisa mengacaukan<select>
nilai default, saya menyelesaikannya dengan memeriksa apakah nilainya diaturbeforeMount()
(dan setel jika tidak) sebagai berikut:JS:
Html:
sumber
Saya ingin memberikan jawaban ini yang membantu menghindari menggunakan banyak kode, pengamat, dan properti yang dihitung. Dalam beberapa kasus ini bisa menjadi solusi yang baik:
Alat peraga dirancang untuk menyediakan komunikasi satu arah.
Ketika Anda memiliki
show/hide
tombol modal dengan properti, solusi terbaik bagi saya adalah memancarkan acara:Kemudian tambahkan pendengar ke elemen modal:
(Dalam hal ini prop
show
mungkin tidak perlu karena Anda dapat menggunakan mudahv-if="show"
langsung pada basis-modal)sumber
Saya pribadi selalu menyarankan jika Anda perlu mengubah alat peraga, pertama-tama berikan mereka ke properti yang dihitung dan kembali dari sana, setelah itu seseorang dapat memutasi alat peraga dengan mudah, bahkan pada saat itu Anda dapat melacak mutasi alat peraga, jika mereka dimutasikan dari yang lain komponen juga atau kami dapat Anda tonton juga.
sumber
Karena alat peraga Vue adalah aliran data satu arah, ini mencegah komponen anak dari secara tidak sengaja mengubah status induk.
Dari dokumen Vue resmi, kami akan menemukan 2 cara untuk menyelesaikan masalah ini
Jika komponen anak ingin menggunakan properti sebagai data lokal, yang terbaik adalah mendefinisikan properti data lokal.
Prop disahkan sebagai nilai mentah yang perlu diubah. Dalam hal ini, yang terbaik adalah mendefinisikan properti yang dihitung menggunakan nilai prop:
sumber
YA !, atribut yang bermutasi di vue2 adalah anti-pola. TAPI ... Hancurkan saja peraturan dengan menggunakan aturan lain, dan teruskan! Yang Anda butuhkan adalah menambahkan .sync modifier ke atribut komponen Anda dalam lingkup paret.
<your-awesome-components :custom-attribute-as-prob.sync="value" />
🤡 Sederhana saja kita membunuh batman 😁
sumber
Untuk saat TypeScript adalah bahasa pilihan Anda. pembangunan
dan tidak
sumber
Di bawah ini adalah komponen snack bar, ketika saya memberikan variabel snackbar langsung ke v-model seperti ini jika akan bekerja tetapi di konsol, itu akan memberikan kesalahan seperti
Hindari mengubah prop secara langsung karena nilai akan ditimpa setiap kali komponen induk dirender kembali. Alih-alih, gunakan data atau properti yang dihitung berdasarkan nilai prop.
Cara yang benar untuk menghilangkan kesalahan mutasi ini adalah menggunakan pengamat
Jadi di komponen utama di mana Anda akan memuat snack bar ini, Anda bisa melakukan kode ini
Ini Berhasil untuk saya
sumber