Disons que j'ai un composant de bouton qui est importé dans plusieurs autres composants. Je souhaite que le composant enfant ne soit associé à aucun type de logique qui survient lorsque l'utilisateur clique sur le bouton. Je souhaite donc conserver cette logique dans les divers composants qui exploitent ce composant de bouton.
Je pense qu'il y a au moins 2 façons de s'y prendre.
Demandez à l'enfant d'émettre un événement aux parents, puis laissez les parents définir le gestionnaire.
Définissez les gestionnaires dans les parents et transmettez-les comme accessoires au composant bouton.
Je suis habitué à faire ce dernier dans React. Y a-t-il une meilleure pratique en vue pour cette situation?
La philosophie de la Vue est les accessoires, les événements. La première option suit cela de plus près au fur et à mesure que l'événement lui-même est émis (au-dessus) du parent puis traité.
Également dans un Vue SFC, vous avez l’avantage supplémentaire de préfixer l’attribut lié avec un v-on (ou @) qui décrit son intention en tant qu’événement se déplaçant vers le haut et non pas un v-bind (ou :) c'est vraiment un rappel à un événement.
La meilleure pratique serait l’option numéro 1. Vous pouvez voir que cette pratique est utilisée dans la documentation officielle: https://vuejs.org/v2/guide/components.html#Sending-Messages-to-Parents-with-Events
Tant que vous transmettez une référence à une fonction à exécuter lorsque vous utilisez le bus d’événements ou que vous transmettez un accessoire, vous ne verrez pratiquement aucune différence de performances.
Vous pouvez utiliser this.$emit('eventName', dataToSend, ...)
pour envoyer les données au composant parent qui l'écouterait ensuite comme suit: <my-component @eventName="yourHandler" />
. Vous pourrez alors utiliser une logique différente pour chaque bouton.
J'ai créé un violon pour un composant à sélections multiples qui implémente ceci: https://jsfiddle.net/wkdL0xbc/
// HTML
<div id="app">
<multi-choice :items="myItems" @selected="alert($event)"></multi-choice>
<multi-choice :items="myItems" @selected="sayIsCool"></multi-choice>
</div>
// JavaScript
const multiChoice = {
template: '<div class="multi-choice"><span v-for="item in items" @click="select(item)">{{ item }}</span></div>',
props: ['items'],
methods: {
select(item) {
this.$emit('selected', item);
}
}
};
new Vue({
el: "#app",
data() {
return {
myItems: [
'Homer',
'Marge',
'Bart'
],
}
},
components: {
multiChoice: multiChoice
},
methods: {
sayIsCool(item) {
alert(item + ' is cool!')
}
}
})
J'étudie toujours Vue.js et je serai ravi de changer quoi que ce soit ici s'il y a des incohérences.
Vue.js events sont des rappels, ce ne sont pas des événements DOM. Vous pouvez le vérifier puisque vous ajoutez un nom personnalisé à l'écouteur d'événement et non un nom d'événement DOM (
click
,focus
...) et qu'aucun objetevent
n'est transmis à la fonction, sauf si vous spécifiez un argument$event
dans l'appel$emit
. .
this.$root.on
), bien que cela puisse être amélioré par Vuex.js.:
pour les props et @
pour les événements/méthodesfunction()
existe avant de l'appeler (mais la validation des accessoires est quand même une bonne pratique ...)On dirait que les approches sont plus conventionnelles et plus personnelles, bien que je pense que sans la documentation de Vue.js donnant la préférence à l'approche events, tout le monde utiliserait volontiers props seulement, qui, à mon avis, est meilleur.
Props peut tout faire events, sauf quelques cas (comme le modèle d'écoute des événements $root
- notant que Vuex.js remplace cette fonctionnalité et est préféré pour l'évolutivité), avec l'avantage qu'ils sont plus explicites, debuggable et enclins à vérifier.
Résumé de: https://forum.vuejs.org/t/events-vs-callback-props/11451
Vous recherchez des «emballages transparents»
L'événement de douane de Vue fonctionne différemment d'un événement DOM natif. Donc, vous devez attacher une propriété .native à l'événement
Mais si vous voulez que l'événement se produise sur l'enfant, vous définissez une propriété calculée qui renverra un objet d'écoute. Et maintenant tu ne le feras pas
Par défaut, les attributs non définis comme accessoires seront ajoutés à l'élément racine de la vue.
Vous pouvez donc définir inheritAttrs: false, puis lier le $ attrs à l'enfant, qui devient alors la cible de ces attributs.
Maintenant, vous n'avez pas à penser à la composante racine.
Chris Fritz fait un excellent travail en expliquant comment ils travaillent dans ses 7 modèles secrets. Commence vers 21:44 https://youtu.be/7lpemgMhi0k?t=21m44s