Saya kesulitan memahami cara melewatkan data antar komponen di vue.js. Saya telah membaca dokumen beberapa kali dan melihat banyak pertanyaan dan tutorial yang berhubungan dengan vue, tetapi saya masih belum mengerti.
Untuk menyelesaikan masalah ini, saya mengharapkan bantuan untuk menyelesaikan contoh yang cukup sederhana
- menampilkan daftar pengguna dalam satu komponen (selesai)
- mengirim data pengguna ke komponen baru ketika tautan diklik (selesai) - lihat pembaruan di bagian bawah.
- edit data pengguna dan kirim kembali ke komponen asli (belum sampai sejauh ini)
Ini biola, yang gagal pada langkah kedua: https://jsfiddle.net/retrogradeMT/d1a8hps0/
Saya memahami bahwa saya perlu menggunakan alat peraga untuk mengirimkan data ke komponen baru, tetapi saya tidak yakin bagaimana cara melakukannya secara fungsional. Bagaimana cara mengikat data ke komponen baru?
HTML:
<div id="page-content">
<router-view></router-view>
</div>
<template id="userBlock" >
<ul>
<li v-for="user in users">{{user.name}} - <a v-link="{ path: '/new' }"> Show new component</a>
</li>
</ul>
</template>
<template id="newtemp" :name ="{{user.name}}">
<form>
<label>Name: </label><input v-model="name">
<input type="submit" value="Submit">
</form>
</template>
js untuk komponen utama:
Vue.component('app-page', {
template: '#userBlock',
data: function() {
return{
users: []
}
},
ready: function () {
this.fetchUsers();
},
methods: {
fetchUsers: function(){
var users = [
{
id: 1,
name: 'tom'
},
{
id: 2,
name: 'brian'
},
{
id: 3,
name: 'sam'
},
];
this.$set('users', users);
}
}
})
JS untuk komponen kedua:
Vue.component('newtemp', {
template: '#newtemp',
props: 'name',
data: function() {
return {
name: name,
}
},
})
MEMPERBARUI
Oke, saya sudah mengetahui langkah kedua. Ini biola baru yang menunjukkan kemajuan: https://jsfiddle.net/retrogradeMT/9pffnmjp/
Karena saya menggunakan Vue-router, saya tidak menggunakan props untuk mengirim data ke komponen baru. Sebagai gantinya, saya perlu mengatur params pada v-link dan kemudian menggunakan hook transisi untuk menerimanya.
Perubahan V-link lihat rute bernama di dokumen vue-router :
<a v-link="{ name: 'new', params: { name: user.name }}"> Show new component</a>
Kemudian pada komponen, tambahkan data ke opsi rute, lihat pengait transisi :
Vue.component('newtemp', {
template: '#newtemp',
route: {
data: function(transition) {
transition.next({
// saving the id which is passed in url
name: transition.to.params.name
});
}
},
data: function() {
return {
name:name,
}
},
})
sumber
params
adalah sebuah objek. Kunci nama dapat ditetapkan kethis.user.name
dalam komponen Anda. Buat biola jika Anda butuh bantuan, dan beri tahu saya. Lihat ini: vuejs.github.io/vue-router/en/route.htmlCara terbaik untuk mengirim data dari komponen induk ke anak menggunakan props .
Meneruskan data dari orang tua ke anak melalui
props
props
(larik atau objek ) pada anak<child :name="variableOnParent">
Lihat demo di bawah ini:
Vue.component('child-comp', { props: ['message'], // declare the props template: '<p>At child-comp, using props in the template: {{ message }}</p>', mounted: function () { console.log('The props are also available in JS:', this.message); } }) new Vue({ el: '#app', data: { variableAtParent: 'DATA FROM PARENT!' } })
<script src="https://unpkg.com/[email protected]/dist/vue.min.js"></script> <div id="app"> <p>At Parent: {{ variableAtParent }}<br>And is reactive (edit it) <input v-model="variableAtParent"></p> <child-comp :message="variableAtParent"></child-comp> </div>
sumber
Vue.set
, selengkapnya di sini: vuejs.org/v2/guide/reactivity.html#For-ArraysSaya pikir masalahnya ada di sini:
<template id="newtemp" :name ="{{user.name}}">
Ketika Anda mengawali prop dengan
:
Anda menunjukkan ke Vue bahwa itu adalah variabel, bukan string. Jadi, Anda tidak membutuhkan{{}}
sekitaruser.name
. Mencoba:<template id="newtemp" :name ="user.name">
EDIT -----
Hal di atas benar, tetapi masalah yang lebih besar di sini adalah ketika Anda mengubah URL dan pergi ke rute baru, komponen asli menghilang. Agar komponen kedua dapat mengedit data induk, komponen kedua harus menjadi komponen turunan dari yang pertama, atau hanya sebagian dari komponen yang sama.
sumber
Saya telah menemukan cara untuk meneruskan data induk ke ruang lingkup komponen di Vue, menurut saya ini sedikit hack tapi mungkin ini akan membantu Anda.
1) Data referensi di Vue Instance sebagai objek eksternal
(data : dataObj)
2) Kemudian pada fungsi data return pada komponen anak tinggal return
parentScope = dataObj
dan voila. Sekarang Anda tidak dapat melakukan hal-hal seperti{{ parentScope.prop }}
dan akan bekerja seperti pesona.Semoga berhasil!
sumber
Respons yang disebutkan di atas berfungsi dengan baik, tetapi jika Anda ingin meneruskan data antara 2 komponen saudara, bus peristiwa juga dapat digunakan. Lihat blog ini yang akan membantu Anda lebih memahami.
misalkan untuk 2 komponen: CompA & CompB memiliki induk dan main.js yang sama untuk menyiapkan aplikasi vue utama. Untuk meneruskan data dari CompA ke CompB tanpa melibatkan komponen induk, Anda dapat melakukan hal berikut.
di file main.js, deklarasikan instance global Vue yang terpisah, yang akan menjadi event bus.
export const bus = new Vue();
Di CompA, tempat acara dibuat: Anda harus memancarkan acara ke bus.
methods: { somethingHappened (){ bus.$emit('changedSomething', 'new data'); } }
Sekarang tugasnya adalah mendengarkan acara yang dipancarkan, jadi, di CompB, Anda bisa mendengarkan seperti.
created (){ bus.$on('changedSomething', (newData) => { console.log(newData); }) }
Keuntungan:
sumber
Saya mengakses properti utama menggunakan
$root
.Vue.component("example", { template: `<div>$root.message</div>` }); ... <example></example>
sumber
Variabel JS global (objek) dapat digunakan untuk melewatkan data antar komponen. Contoh: Meneruskan data dari Ammlogin.vue ke Options.vue. Dalam Ammlogin.vue rspData diatur ke respon dari server. Di Options.vue, respons dari server tersedia melalui rspData.
index.html:
<script> var rspData; // global - transfer data between components </script>
Ammlogin.vue:
.... export default { data: function() {return vueData}, methods: { login: function(event){ event.preventDefault(); // otherwise the page is submitted... vueData.errortxt = ""; axios.post('http://vueamm...../actions.php', { action: this.$data.action, user: this.$data.user, password: this.$data.password}) .then(function (response) { vueData.user = ''; vueData.password = ''; // activate v-link via JS click... // JSON.parse is not needed because it is already an object if (response.data.result === "ok") { rspData = response.data; // set global rspData document.getElementById("loginid").click(); } else { vueData.errortxt = "Felaktig avändare eller lösenord!" } }) .catch(function (error) { // Wu oh! Something went wrong vueData.errortxt = error.message; }); }, ....
Options.vue:
<template> <main-layout> <p>Alternativ</p> <p>Resultat: {{rspData.result}}</p> <p>Meddelande: {{rspData.data}}</p> <v-link href='/'>Logga ut</v-link> </main-layout> </template> <script> import MainLayout from '../layouts/Main.vue' import VLink from '../components/VLink.vue' var optData = { rspData: rspData}; // rspData is global export default { data: function() {return optData}, components: { MainLayout, VLink } } </script>
sumber