Jadi saya ingin meneruskan props ke sebuah komponen Vue, tapi saya berharap props ini berubah di masa depan dari dalam komponen itu misalnya ketika saya mengupdate komponen Vue dari dalam menggunakan AJAX. Jadi mereka hanya untuk inisialisasi komponen.
cars-list
Elemen komponen Vue saya tempat saya meneruskan props dengan properti awal ke single-car
:
// cars-list.vue
<script>
export default {
data: function() {
return {
cars: [
{
color: 'red',
maxSpeed: 200,
},
{
color: 'blue',
maxSpeed: 195,
},
]
}
},
}
</script>
<template>
<div>
<template v-for="car in cars">
<single-car :initial-properties="car"></single-car>
</template>
</div>
</template>
Cara saya melakukannya sekarang ini bahwa di dalam saya single-car
komponen Aku menugaskan this.initialProperties
ke saya this.data.properties
di created()
inisialisasi kail. Dan itu bekerja dan reaktif.
// single-car.vue
<script>
export default {
data: function() {
return {
properties: {},
}
},
created: function(){
this.data.properties = this.initialProperties;
},
}
</script>
<template>
<div>Car is in {{properties.color}} and has a max speed of {{properties.maxSpeed}}</div>
</template>
Tapi masalah saya dengan itu adalah saya tidak tahu apakah itu cara yang benar untuk melakukannya? Tidakkah itu akan membuat saya mengalami beberapa masalah di sepanjang jalan? Atau apakah ada cara yang lebih baik untuk melakukannya?
sumber
data
yangtwo-way
terikat, tetapi Anda tidak bisa lewatdata
ke komponen, Anda lulusprops
, tetapi Anda tidak dapat mengubah diterimaprops
atau mengkonversiprops
kedata
. Lalu apa? Satu hal yang saya pelajari adalah Anda harusprops
menurunkan dan memicu peristiwa. Artinya, jika komponen ingin mengubahprops
penerimaannya, itu harus memanggil peristiwa dan "dirender". Tapi kemudian Anda pergi denganone-way
pengikatan persis seperti React dan saya tidak melihat gunanya untukdata
itu. Cukup membingungkan.Jawaban:
Berkat https://github.com/vuejs/vuejs.org/pull/567 ini saya tahu jawabannya sekarang.
Metode 1
Meneruskan prop awal langsung ke data. Seperti contoh di dokumen yang diperbarui:
props: ['initialCounter'], data: function () { return { counter: this.initialCounter } }
Namun perlu diingat jika prop yang diteruskan adalah objek atau larik yang digunakan dalam status komponen induk, modifikasi apa pun pada prop itu akan mengakibatkan perubahan dalam status komponen induk tersebut.
Peringatan : metode ini tidak disarankan. Ini akan membuat komponen Anda tidak dapat diprediksi. Jika Anda perlu menyetel data induk dari komponen anak baik gunakan manajemen negara seperti Vuex atau gunakan "v-model". https://vuejs.org/v2/guide/components.html#Using-v-model-on-Components
Metode 2
Jika prop awal Anda adalah sebuah objek atau larik dan jika Anda tidak ingin perubahan dalam status anak disebarkan ke status induk maka cukup gunakan eg
Vue.util.extend
[1] untuk membuat salinan dari props alih-alih mengarahkannya langsung ke data anak, seperti ini:props: ['initialCounter'], data: function () { return { counter: Vue.util.extend({}, this.initialCounter) } }
Metode 3
Anda juga dapat menggunakan operator penyebaran untuk mengkloning alat peraga. Detail lebih lanjut di jawaban Igor: https://stackoverflow.com/a/51911118/3143704
Namun perlu diingat bahwa operator penyebaran tidak didukung di browser lama dan untuk kompatibilitas yang lebih baik Anda perlu mentranspilasi kode, misalnya menggunakan
babel
.Catatan kaki
[1] Ingatlah bahwa ini adalah utilitas Vue internal dan dapat berubah dengan versi baru. Anda mungkin ingin menggunakan metode lain untuk menyalin properti itu, lihat " Bagaimana cara saya mengkloning objek JavaScript dengan benar? ".
Biola saya tempat saya mengujinya: https://jsfiddle.net/sm4kx7p9/3/
sumber
{ ok: 1, notOk: { meh: 2 } }
jika disetel ke data internal dengan salah satu metode kloning sebelumnya masih akan mengubah propnotOk.meh
initial
hanya untuk dapat menggunakannya dalam comp saya. Akan jauh lebih bersih jika kita bisa melewatkan prop yang dipanggildata
ke comp mana pun dan membuatnya secara otomatis menyebarkan data yang dilokalkan di dalamnya tanpa semuainitialPropName
kegilaan ini .prop --> comp.data
menggunakan Vue-Stash untuk semua data (atau Vuex juga akan berfungsi). Tapi sekarang saya hanya memantulkan data saya dariwindow
objek seperti yang biasa saya lakukan sebelum framework JS "modern" memberlakukan opini mereka pada saya. Jadi ini menimbulkan pertanyaan: Apa gunanya properti comp.data?Dalam pendamping jawaban @ dominik-serafin:
Jika Anda mengirimkan objek, Anda dapat dengan mudah mengkloningnya menggunakan operator penyebaran (Sintaks ES6):
props: { record: { type: Object, required: true } }, data () { // opt. 1 return { recordLocal: {...this.record} } }, computed: { // opt. 2 recordLocal () { return {...this.record} } },
Tapi yang paling penting adalah ingat untuk menggunakan opt. 2 jika Anda meneruskan nilai yang dihitung, atau lebih dari itu nilai asynchronous. Jika tidak, nilai lokal tidak akan diperbarui.
Demo:
Vue.component('card', { template: '#app2', props: { test1: null, test2: null }, data () { // opt. 1 return { test1AsData: {...this.test1} } }, computed: { // opt. 2 test2AsComputed () { return {...this.test2} } } }) new Vue({ el: "#app1", data () { return { test1: {1: 'will not update'}, test2: {2: 'will update after 1 second'} } }, mounted () { setTimeout(() => { this.test1 = {1: 'updated!'} this.test2 = {2: 'updated!'} }, 1000) } })
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script> <div id="app1"> <card :test1="test1" :test2="test2"></card> </div> <template id="app2"> <div> test1 as data: {{test1AsData}} <hr /> test2 as computed: {{test2AsComputed}} </div> </template>
https://jsfiddle.net/nomikos3/eywraw8t/281070/
sumber
recordLocal: [...this.record]
(dalam catatan kasus saya adalah array) tidak berfungsi untuk saya - setelah memuat dan memeriksa komponen vue,record
berisi item danrecordLocal
merupakan array kosong.computed
Saya yakin Anda melakukannya dengan benar karena itulah yang dinyatakan dalam dokumen.
https://vuejs.org/guide/components.html#One-Way-Data-Flow
sumber
window
objek.