Maison > Article > interface Web > Comment communiquer entre les composants de vue ? Présentation de la méthode
Communication entre composants
Bien qu'un composant enfant puisse utiliser this.$parent pour accéder à son composant parent et à toute instance de sa chaîne parent, Child les composants doivent éviter de s'appuyer directement sur les données du composant parent et essayer d'utiliser explicitement des accessoires pour transmettre des données.
De plus, c'est une très mauvaise pratique de modifier l'état du composant parent dans le composant enfant car :
Cela rend le composant parent et le composant enfant étroitement couplé;
Il est difficile de comprendre l'état du composant parent uniquement en le regardant. Parce qu'il peut être modifié par n'importe quel sous-composant ! Idéalement, seul le composant lui-même peut modifier son état.
Chaque instance de Vue est un déclencheur d'événement :
$on() - écoutez les événements.
$emit() - répartit les événements en haut de la chaîne de portée. (Événement déclencheur)
$dispatch() - Distribue un événement qui bouillonne le long de la chaîne parent.
$broadcast() - Événements de diffusion, qui sont transmis à tous les descendants.
Écoute et déclenchement
v-on écoute les événements personnalisés :
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <!--子组件模板--> <template id="child-template"> <input v-model="msg" /> <button v-on:click="notify">Dispatch Event</button> </template> <!--父组件模板--> <div id="events-example"> <p>Messages: {{ messages | json }}</p> <child v-on:child-msg="handleIt"></child> </div> </body> <script src="js/vue.js"></script> <script> // 注册子组件 // 将当前消息派发出去 Vue.component('child', { template: '#child-template', data: function (){ return { msg: 'hello' } }, methods: { notify: function() { if(this.msg.trim()){ this.$dispatch('child-msg',this.msg); this.msg = ''; } } } }) // 初始化父组件 // 在收到消息时将事件推入一个数组中 var parent = new Vue({ el: '#events-example', data: { messages: [] }, methods:{ 'handleIt': function(){ alert("a"); } } }) </script> </html>
Le composant parent peut utiliser directement v-on où le composant enfant est utilisé pour écouter les événements déclenchés par le composant enfant :
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <div id="counter-event-example"> <p>{{ total }}</p> <button-counter v-on:increment="incrementTotal"></button-counter> <button-counter v-on:increment="incrementTotal"></button-counter> </div> </body> <script src="js/vue.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> Vue.component('button-counter', { template: '<button v-on:click="increment">{{ counter }}</button>', data: function () { return { counter: 0 } }, methods: { increment: function () { this.counter += 1 this.$emit('increment') } }, }) new Vue({ el: '#counter-event-example', data: { total: 0 }, methods: { incrementTotal: function () { this.total += 1 } } }) </script> </html>
Écouter un élément natif sur le élément racine d’un événement de composant. Vous pouvez utiliser .native pour modifier v-on. Par exemple :
<my-component v-on:click.native="doTheThing"></my-component>
distribue des événements - $dispatch()
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <div id="app"> <p>Messages: {{ messages | json }}</p> <child-component></child-component> </div> <template id="child-component"> <input v-model="msg" /> <button v-on:click="notify">Dispatch Event</button> </template> <script src="js/vue.js"></script> <script> // 注册子组件 Vue.component('child-component', { template: '#child-component', data: function() { return { msg: '' } }, methods: { notify: function() { if (this.msg.trim()) { this.$dispatch('child-msg', this.msg) this.msg = '' } } } }) // 初始化父组件 new Vue({ el: '#app', data: { messages: [] }, events: { 'child-msg': function(msg) { this.messages.push(msg) } } }) </script> </body> </html>
L'élément bouton du sous-composant est lié à l'événement click. Cet événement pointe vers la méthode notify
Lors du traitement de la méthode notify du composant enfant, il appelle $dispatch, distribue l'événement à l'événement child-msg du parent. composant et fournit l'événement avec un paramètre msg
définit l'événement child-msg dans l'option events du composant parent. Une fois que le composant parent a reçu l'envoi du composant enfant, il. appelle l'événement child-msg.
Événement de diffusion - $broadcast()
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <div id="app"> <input v-model="msg" /> <button v-on:click="notify">Broadcast Event</button> <child-component></child-component> </div> <template id="child-component"> <ul> <li v-for="item in messages"> 父组件录入了信息:{{ item }} </li> </ul> </template> <script src="js/vue.js"></script> <script> // 注册子组件 Vue.component('child-component', { template: '#child-component', data: function() { return { messages: [] } }, events: { 'parent-msg': function(msg) { this.messages.push(msg) } } }) // 初始化父组件 new Vue({ el: '#app', data: { msg: '' }, methods: { notify: function() { if (this.msg.trim()) { this.$broadcast('parent-msg', this.msg) } } } }) </script> </body> </html>
L'opposé de l'événement de répartition. Le premier est lié au composant enfant et appelle $dispatch pour distribuer au composant parent ; le second est lié au composant parent et appelle $broadcast pour diffuser au composant enfant.
Accès entre les composants parent et enfant
Composant parent pour accéder aux composants enfants : utilisez $children ou $refs
Les composants enfants accèdent au composant parent : utilisez $parent
Les composants enfants accèdent au composant racine : utilisez $root
$ children:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <div id="app"> <parent-component></parent-component> </div> <template id="parent-component"> <child-component1></child-component1> <child-component2></child-component2> <button v-on:click="showChildComponentData">显示子组件的数据</button> </template> <template id="child-component1"> <h2>This is child component 1</h2> </template> <template id="child-component2"> <h2>This is child component 2</h2> </template> <script src="js/vue.js"></script> <script> Vue.component('parent-component', { template: '#parent-component', components: { 'child-component1': { template: '#child-component1', data: function() { return { msg: 'child component 111111' } } }, 'child-component2': { template: '#child-component2', data: function() { return { msg: 'child component 222222' } } } }, methods: { showChildComponentData: function() { for (var i = 0; i < this.$children.length; i++) { alert(this.$children[i].msg) } } } }) new Vue({ el: '#app' }) </script> </body> </html>
$ref peut spécifier l'ID d'index pour les composants enfants :
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <div id="app"> <parent-component></parent-component> </div> <template id="parent-component"> <!--<child-component1></child-component1> <child-component2></child-component2>--> <child-component1 v-ref:cc1></child-component1> <child-component2 v-ref:cc2></child-component2> <button v-on:click="showChildComponentData">显示子组件的数据</button> </template> <template id="child-component1"> <h2>This is child component 1</h2> </template> <template id="child-component2"> <h2>This is child component 2</h2> </template> <script src="js/vue.js"></script> <script> Vue.component('parent-component', { template: '#parent-component', components: { 'child-component1': { template: '#child-component1', data: function() { return { msg: 'child component 111111' } } }, 'child-component2': { template: '#child-component2', data: function() { return { msg: 'child component 222222' } } } }, methods: { showChildComponentData: function() { // for (var i = 0; i < this.$children.length; i++) { // alert(this.$children[i].msg) // } alert(this.$refs.cc1.msg); alert(this.$refs.cc2.msg); } } }) new Vue({ el: '#app' }) </script> </body> </html>
L'effet est le même que $children.
$parent :
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <div id="app"> <parent-component></parent-component> </div> <template id="parent-component"> <child-component></child-component> </template> <template id="child-component"> <h2>This is a child component</h2> <button v-on:click="showParentComponentData">显示父组件的数据</button> </template> <script src="js/vue.js"></script> <script> Vue.component('parent-component', { template: '#parent-component', components: { 'child-component': { template: '#child-component', methods: { showParentComponentData: function() { alert(this.$parent.msg) } } } }, data: function() { return { msg: 'parent component message' } } }) new Vue({ el: '#app' }) </script> </body> </html>
Comme mentionné au début, il n'est pas recommandé de modifier le statut du composant parent dans le composant enfant.
Communication entre composants non parent-enfant
Parfois, les composants ayant une relation non parent-enfant doivent également communiquer. Dans un scénario simple, utilisez une instance Vue vide comme bus d'événements central :
var bus = new Vue() // 触发组件 A 中的事件 bus.$emit('id-selected', 1) // 在组件 B 创建的钩子中监听事件 bus.$on('id-selected', function (id) { // ... })
Recommandations associées :
Un résumé des questions d'entretien Vue frontale en 2020 (Avec réponses)
Recommandations du didacticiel Vue : les 5 dernières sélections de didacticiels vidéo vue.js en 2020
Plus de connaissances liées à la programmation , Veuillez visiter : Introduction à la programmation ! !
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!