Aller au contenu principal

Mettre à jour une propriété d'un composant Vuejs utilisé avec v-for

Imaginons que vous ayez besoin de créer une liste avec Vuejs.

Pour cela vous créez un composant (appelé ici "fueltypes") qui aurait comme template un élément <li> et que vous inclurez de la manière suivante :

            <ul class="tabs">
                <fueltypes
                        v-for="fueltype in fueltypes"
                        v-bind:fueltype="fueltype"
                        :key="fueltype.value">
                </fueltypes>
            </ul>

Imaginons maintenant que vous voudriez qu'une classe soit appliquée sur un seul de ces éléments rendus lorsqu'on clique dessus. Dans un premier temps, on ajouterait un événement "on-click" sur chaque élément rendu et cet événement changerait une propriété (link_active) du composant. Petit soucis, lorsque vous allez cliquer sur l'élément, les autres éléments sur lesquels vous aurez déjà cliqué ne changeront pas (la classe sera toujours présente). Solution : ajouter un événement (change-link-active) sur le composant qui changerait la propriété pour chaque élément rendu avec le v-for :

           <ul class="tabs">
                <fueltypes
                        v-for="fueltype in fueltypes"
                        v-bind:fueltype="fueltype"
                        :link_active="link_active"
                        @change-link-active="link_active = $event"
                        :key="fueltype.value">
                </fueltypes>
            </ul>

Dans la méthode (changeActiveClass) appelée sur l'événement "on-click" dans notre composant il faudra appeler $emit avec une valeur unique (ici fueltype.id) qui sera passé en paramètre pour déclencher notre événement "change-link-active". Cette valeur unique sera utilisée pour la condition pour afficher la classe ou pas sur l'élément :

 <template>
  <li class="tab">
    <div class="col-md-12">
      <a v-bind:id="'fuel_type_'+fueltype.class"
         v-bind:href="'#'+fueltype.class"
         @click="changeActiveClass(fueltype.id)"
         v-bind:class="[fueltype.class, {active:link_active == fueltype.id} ]">
        {{ fueltype.label }}
      </a>
    </div>
  </li>
</template>
<script>
    export default {
        props: {
            fueltype: {
                type: Object,
                required: true
            },
            link_active: {
                type: Number,
                required: false
            },
        },
        methods: {
            changeActiveClass (id) {
                this.$emit('change-link-active', id);
            }
        },
    }
</script>

Étiquettes