2
votes

Vue.Js, lier une valeur à une case à cocher dans un composant

Je crée un composant qui est un wrapper autour d'une case à cocher (j'ai fait la même chose avec des entrées de type 'text' et 'number') mais je ne parviens pas à faire passer ma valeur pour lier correctement.

Mon le composant est:

<check-edit name="ShowInCalendar" v-model="model.ShowInCalendar" label="Show in calendar?" :errors="this.errors.ShowInCalendar"></check-edit>

Je l'ai importé globalement; et je l'invoque dans une autre vue en faisant:

<template>
  <div class="field">
    <label :for="name" class="label">
      {{ label }}
    </label>
    <div class="control">
      <input :id="name" :name="name" type="checkbox" class="control" :checked="value" v-on="listeners" />
    </div>
    <p v-show="this.hasErrors" class="help has-text-danger">
      <ul>
        <li v-for="error in errors" :key="error">{{ error }}</li>
      </ul>
    </p>
  </div>
</template>
<script>
export default {
  name: 'check-edit',
  props: {
    value: {
      type: Boolean,
      default: false
    },
    label: {
      type: String,
      default: ''
    },
    name: {
      type: String,
      default: ''
    },
    errors: {
      type: Array,
      default: () => []
    }
  },
  mounted () {
  },
  computed: {
    listeners () {
      return {
        // Pass all component listeners directly to input
        ...this.$listeners,
        // Override input listener to work with v-model
        input: event => this.$emit('input', event.target.value)
      }
    },
    hasErrors () {
      return this.errors.length > 0
    }
  },
}
</script>

Mon modèle est dans les données et la propriété ShowInCalendar est un booléen et dans mon cas de test est vrai. Ainsi, lorsque je regarde la page, la case est cochée. En utilisant les outils Vue dans Firefox, je peux voir le modèle.ShowInCalendar est vrai et la case est cochée. Cependant, lorsque je clique dessus, la case reste cochée et la valeur de ShowInCalendar change en 'on', puis les modifications par la suite ne changent pas la valeur de ShowInCalendar.

J'ai trouvé cet exemple ici: https://jsfiddle.net/robertkern/oovb8ym7/ et ont essayé d'implémenter une propriété de données locale pour cela mais le résultat ne fonctionne pas.

Le nœud de ce que j'essaie de faire est que l'état de contrôle initial de la case à cocher soit celui de ShowInCalendar (ou toute propriété liée via v-model sur le composant), puis cette propriété doit être mise à jour (pour être vraie ou fausse) lorsque la case est cochée.

Quelqu'un peut-il me donner des conseils s'il vous plaît?

Merci.


0 commentaires

3 Réponses :


1
votes

Ne changez pas d'accessoires. Votre composant, ayant un v-model , doit être émission d'événements d'entrée en cas de modification . Le parent gérera le changement réel de la valeur.


1 commentaires

D'accord, cela a du sens. J'avais une version qui utilisait get and set sur les accessoires qui semblaient plus maladroits, et retournait le même résultat.



3
votes

Si v-on est le seul écouteur qui sera utilisé, il pourrait être plus facile d'utiliser v-model comme dans l'exemple de case à cocher de Documentation d'entrée Vue .

Cependant, vous pouvez utiliser des écouteurs basés sur Binding-Native-Events-to-Components documents

<template>
  <div class="field">
    <label :for="name" class="label">
      {{ label }}
    </label>
    <div class="control">
      <input :id="name" :name="name" type="checkbox" class="control" checked="value" v-on="listeners" />
    </div>
    <p v-show="this.hasErrors" class="help has-text-danger">
      <ul>
        <li v-for="error in errors" :key="error">{{ error }}</li>
      </ul>
    </p>
  </div>
</template>
<script>
export default {
    name: 'check-edit',
    props: {
        value: {
            type: Boolean,
            default: false
        },
        label: {
            type: String,
            default: ''
        },
        name: {
            type: String,
            default: ''
        },
        errors: {
            type: Array,
            default: () => []
        }
    },
    mounted() {},
    computed: {
        listeners() {
            var vm = this;
            // `Object.assign` merges objects together to form a new object
            return Object.assign(
                {},
                // We add all the listeners from the parent
                this.$listeners,
                // Then we can add custom listeners or override the
                // behavior of some listeners.
                {
                    // This ensures that the component works with v-model
                    input: function(event) {
                        vm.$emit('input', event.target.checked);
                    }
                }
            );
        },
        hasErrors() {
            return this.errors.length > 0;
        }
    }
};
</script>



1 commentaires

Merci, je vois ce que tu veux dire.



5
votes

Vous ne devez pas $ emit event.target.value , c'est la valeur de la case à cocher, ce n'est pas une valeur booléenne. Si vous voulez détecter que la case à cocher est mise à jour (qu'elle soit vraie ou fausse) ou non, vous devez $ emit event.target.checked comme l'a dit fstep.


1 commentaires

Merci, je n'ai pas apprécié que vous ayez spécifié la propriété qui a été retournée.