5 votes

Composant Vue sans rendu avec un récepteur de clics

J'ai lu cet article qui traite en profondeur des composants sans rendu :

https://adamwathan.me/renderless-components-in-vuejs/

Un composant sans rendu ressemblerait à peu près à ceci :

export default {
  render() {
    return this.$scopedSlots.default({})
  },
}

J'aimerais maintenant utiliser ce composant sans rendu, mais aussi ajouter un récepteur de clic à ce qui est passé dans la fente.

Dans mon cas, il s'agit d'un bouton. Mon composant sans rendu envelopperait simplement un bouton et lui ajouterait un récepteur de clic, qui à son tour exécuterait une requête AJAX.

Comment puis-je ajouter un récepteur de clic à l'élément qui est passé dans la fente ?

4voto

Richard Matsen Points 7624

En supposant que vous souhaitiez lier le gestionnaire de clic à l'intérieur du composant sans rendu, je pense qu'à partir de ce poste que vous devez cloner le vnode passé en renderless afin d'en améliorer les propriétés.

Voir createElements Arguments le second arg est l'objet à améliorer

Un objet de données correspondant aux attributs que vous utiliseriez dans un modèle. Facultatif.

console.clear()
Vue.component('renderless', {
  render(createElement) {
    var vNode = this.$scopedSlots.default()[0]
    var children  = vNode.children || vNode.text
    const clone = createElement(
      vNode.tag, 
      {
        ...vNode.data, 
        on: { click: () => alert('clicked') }
      },
      children
    )
    return clone
  },
});
new Vue({}).$mount('#app');

<script src="https://unpkg.com/vue@2.6.11/dist/vue.js"></script>

<div id="app">
  <renderless>
    <button type="button" slot-scope="{props}">Click me</button>
  </renderless>
</div>

0voto

miqh Points 2700

Voici une façon de procéder.

Votre enveloppe de composant sans rendu se compose d'un seul élément action (c'est-à-dire la fonction qui émet la requête AJAX) prop.

Vue.component('renderless-action-wrapper', {
  props: ['action'],
  render() {
    return this.$scopedSlots.default({
      action: this.action,
    });
  },
});

Ensuite, un autre composant qui utilise l'enveloppe susmentionnée renfermerait une fente personnalisable avec une balise @click qui invoque l'action transmise lors du déclenchement.

Vue.component('clickable', {
  props: ['action'],
  template: `
    <renderless-action-wrapper :action="action">
      <span slot-scope="{ url, action }">
        <span @click="action()">
          <slot name="action"></slot>
        </span>
      </span>
    </renderless-action-wrapper>
  `,
});

Enfin, il faut câbler la version spécialisée de l'enveloppe.

<clickable :action="doAjaxRequest">
  <button type="button" slot="action">Button</button>
</clickable>

Voici un exemple concret de la suggestion ci-dessus avec laquelle vous pouvez jouer.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X