web-dev-qa-db-fra.com

vue, fonction émettrice ou passante comme accessoire

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. 

  1. Demandez à l'enfant d'émettre un événement aux parents, puis laissez les parents définir le gestionnaire.

  2. 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?

6
Andrew Kim

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.

10
Shelton Clinard

Meilleur entrainement

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

Performance

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.

Exemple utilisant l'option numéro 1

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!')
    }
  }
})
4
atlazor

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 objet event n'est transmis à la fonction, sauf si vous spécifiez un argument $event dans l'appel $emit. .

Événements

Avantages

  • Pour les bibliothèques: garde le moins de poids possible et offre aux clients plus de souplesse dans l'utilisation des méthodes
  • Vue devtools de Vue devtools
  • Autoriser l'écouteur global (this.$root.on), bien que cela puisse être amélioré par Vuex.js.
  • Syntaxe différenciée: : pour les props et @ pour les événements/méthodes

Les inconvénients

  • Moins explicite, plus difficile à déboguer (échec en mode silencieux s'il n'y a pas d'écouteur ou si le nom de l'événement est mal orthographié)

Les accessoires

Avantages

  • Plus explicites, sont déclaratives, peuvent être configurées par défaut, obligatoires, validées, ce qui les rend plus faciles à déboguer (erreurs d’exécution ou de compilation dans TypeScript)

Les inconvénients

  • Vous devez inclure la validation des accessoires afin de ne pas avoir à vérifier si un accessoire function() existe avant de l'appeler (mais la validation des accessoires est quand même une bonne pratique ...)

Conclusion

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

3
jpenna

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

0
Adam Bradford