Saya memiliki dua komponen bersarang, apa cara yang tepat untuk mengakses metode anak dari induknya?
this.$children[0].myMethod()
tampaknya melakukan trik tetapi itu cukup jelek, bukan, cara apa yang bisa lebih baik:
<script>
import child from './my-child'
export default {
components: {
child
},
mounted () {
this.$children[0].myMethod()
}
}
</script>
javascript
vue.js
al3x
sumber
sumber
Jawaban:
Anda dapat menggunakan ref .
import ChildForm from './components/ChildForm' new Vue({ el: '#app', data: { item: {} }, template: ` <div> <ChildForm :item="item" ref="form" /> <button type="submit" @click.prevent="submit">Post</button> </div> `, methods: { submit() { this.$refs.form.submit() } }, components: { ChildForm }, })
Jika Anda tidak menyukai kopling yang ketat, Anda dapat menggunakan Bus Acara seperti yang ditunjukkan oleh @Yosvel Quintero. Di bawah ini adalah contoh lain menggunakan bus acara dengan melewati bus sebagai alat peraga.
import ChildForm from './components/ChildForm' new Vue({ el: '#app', data: { item: {}, bus: new Vue(), }, template: ` <div> <ChildForm :item="item" :bus="bus" ref="form" /> <button type="submit" @click.prevent="submit">Post</button> </div> `, methods: { submit() { this.bus.$emit('submit') } }, components: { ChildForm }, })
Kode komponen.
<template> ... </template> <script> export default { name: 'NowForm', props: ['item', 'bus'], methods: { submit() { ... } }, mounted() { this.bus.$on('submit', this.submit) }, } </script>
https://code.luasoftware.com/tutorials/vuejs/parent-call-child-component-method/
sumber
this.$refs.
, Anda tidak boleh memuat komponen turunan secara dinamis.this.$ref.ref
tampaknya mengembalikan array. Jadi bagi sayathis.$refs.ref[0].autofocus();
bekerjaKomunikasi orang tua-anak di VueJS
Mengingat instance root Vue dapat diakses oleh semua turunan melalui
this.$root
, komponen induk dapat mengakses komponen turunan melaluithis.$children
larik, dan komponen turunan dapat mengakses induknya melaluithis.$parent
, insting pertama Anda mungkin mengakses komponen ini secara langsung.Dokumentasi VueJS memperingatkan hal ini secara khusus karena dua alasan yang sangat bagus:
Solusinya adalah dengan menggunakan antarmuka acara khusus Vue
Antarmuka acara yang diimplementasikan oleh Vue memungkinkan Anda untuk berkomunikasi naik turun pohon komponen. Memanfaatkan antarmuka acara khusus memberi Anda akses ke empat metode:
$on()
- memungkinkan Anda untuk mendeklarasikan listener pada instance Vue Anda yang akan digunakan untuk mendengarkan peristiwa$emit()
- memungkinkan Anda untuk memicu peristiwa pada contoh yang sama (sendiri)Contoh penggunaan
$on()
dan$emit()
:const events = new Vue({}), parentComponent = new Vue({ el: '#parent', ready() { events.$on('eventGreet', () => { this.parentMsg = `I heard the greeting event from Child component ${++this.counter} times..`; }); }, data: { parentMsg: 'I am listening for an event..', counter: 0 } }), childComponent = new Vue({ el: '#child', methods: { greet: function () { events.$emit('eventGreet'); this.childMsg = `I am firing greeting event ${++this.counter} times..`; } }, data: { childMsg: 'I am getting ready to fire an event.', counter: 0 } });
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.28/vue.min.js"></script> <div id="parent"> <h2>Parent Component</h2> <p>{{parentMsg}}</p> </div> <div id="child"> <h2>Child Component</h2> <p>{{childMsg}}</p> <button v-on:click="greet">Greet</button> </div>
Jawaban diambil dari posting asli: Berkomunikasi antar komponen di VueJS
sumber
Ref dan event bus keduanya memiliki masalah saat render kontrol Anda terpengaruh oleh
v-if
. Jadi, saya memutuskan untuk menggunakan metode yang lebih sederhana.Idenya adalah menggunakan array sebagai antrian untuk mengirim metode yang perlu dipanggil ke komponen anak. Setelah komponen dipasang, itu akan memproses antrian ini. Ini melihat antrian untuk menjalankan metode baru.
(Meminjam beberapa kode dari jawaban Desmond Lua)
Kode komponen induk:
import ChildComponent from './components/ChildComponent' new Vue({ el: '#app', data: { item: {}, childMethodsQueue: [], }, template: ` <div> <ChildComponent :item="item" :methods-queue="childMethodsQueue" /> <button type="submit" @click.prevent="submit">Post</button> </div> `, methods: { submit() { this.childMethodsQueue.push({name: ChildComponent.methods.save.name, params: {}}) } }, components: { ChildComponent }, })
Ini adalah kode untuk ChildComponent
<template> ... </template> <script> export default { name: 'ChildComponent', props: { methodsQueue: { type: Array }, }, watch: { methodsQueue: function () { this.processMethodsQueue() }, }, mounted() { this.processMethodsQueue() }, methods: { save() { console.log("Child saved...") }, processMethodsQueue() { if (!this.methodsQueue) return let len = this.methodsQueue.length for (let i = 0; i < len; i++) { let method = this.methodsQueue.shift() this[method.name](method.params) } }, }, } </script>
Dan ada banyak ruang untuk perbaikan seperti pindah
processMethodsQueue
ke mixin ...sumber
Untuk mengkomunikasikan komponen anak dengan komponen anak lain saya telah membuat metode di induk yang memanggil metode pada anak dengan:
this.$refs.childMethod()
Dan dari anak lain saya telah memanggil metode root:
this.$root.theRootMethod()
Itu berhasil untuk saya.
sumber