Le composant grand-parent dans VueJs 3 envoie des événements à son composant grand-parent
P粉251903163
P粉251903163 2023-11-03 16:03:06
0
2
750

Je suis relativement nouveau sur Vue et je travaille sur mon premier projet. J'essaie de créer un formulaire avec plusieurs composants enfants et petits-enfants. J'ai rencontré un problème où je dois pouvoir générer plusieurs copies d'un formulaire. Par conséquent, j'ai déplacé certains attributs de données vers le haut d'un niveau. Actuellement, le formulaire est ApplicationPage.Vue > TheApplication.Vue > Mon problème est que je dois émettre des modifications de PersonalInformation vers ApplicationPage via TheApplication . J'ai du mal à comprendre comment gérer cette situation. J'ai cherché une solution pour Vue2 mais je n'ai pas trouvé de solution pour Vue3.

ApplicationPage.vue

template
      <TheApplication :petOptions="petOptions"
                      :stateOptions='stateOptions'
                      v-model="data.primary"
                      applicant="Primary"/>

script
data() {
    return {
      data: {
        primary: {
          personalInformation: {
            first_name: "",
            middle_name: "",
            last_name: "",
            date_of_birth: "",
            phone: null,
            email: "",
            pets: "",
            driver_license: null,
            driver_license_state: "",
            number_of_pets: null,
            additional_comments: ""
          },
        },
      },
    }
  },

L'Application.Vue

<personal-information :petOptions="petOptions"
                                  :stateOptions='stateOptions'
                                  :personalInformation="modelValue.personalInformation"
                                  @updateField="UpdateField"
            />
methods: {
    UpdateField(field, value) {
      this.$emit('update:modelValue', {...this.modelValue, [field]: value})
    },

informations personnelles.vue

<base-input :value="personalInformation.first_name"
                  @change="onInput('personalInformation.first_name', $event.target.value)"
                  label="First Name*"
                  type="text" class=""
                  required/>
methods: {
    onInput(field, value) {
      console.log(field + " " + value)
      // this.$emit('updateField', { ...this.personalInformation, [field]: value })
      this.$emit('updateField', field, value)
    },
  }


P粉251903163
P粉251903163

répondre à tous(2)
P粉037880905

Pour tous ceux qui ne souhaitent pas lier l'événement émis, il y a un objet parent sur l'objet enfant qui peut également être utilisé pour émettre des événements. Assurez-vous d'enregistrer le lancement dans le parent pour éviter les avertissements dans la console.

Enfants

Appelez le parent direct $emitici.

Enfant.vue

<input @input="$parent.$emit('custom-event', e.target.value) />

Ou comment l'utiliser :

<input @input="handleInput" />
export default {
  methods: {
    handleInput(e) {
      this.$parent.$emit('custom-event', e.target.value)
    }
  }
}

Parent

Puisque c'est le parent qui signale l'ancêtre, déclarez l'émission ici. Pour ,只需使用 defineEmits() méthode pour déclarer l’émission. Veuillez vous référer à la Documentation.

Parent.vue

<Child /> <!-- No need to listen to the event here -->
export default {
   emits: ['custom-event'] // Register the emits
}

Si vous utilisez

<script setup>
  defineEmits(['custom-event']) // Register the emits
</script>

Grands-parents

Ensuite, écoutez l'événement dans le composant grand-parent.

GrandParent.vue

<Parent @custom-event="doSomething()" /> <!-- The event is being listened to in the grandparent component -->
P粉842215006

Voici comment je procède : codesandbox

Emits n'accepte que deux paramètres, le nom à émettre et la valeur à émettre. Si plusieurs valeurs sont émises, elles doivent être émises comme un seul objet. Dans ma solution, le composant Sun émet le nom et la valeur du champ comme un seul objet

petit-fils

<input
    :value="personalInformation.first_name"
    @input="onInput('first_name', $event.target.value)"
    ...
>
onInput(field, value) {
  this.$emit("update-field", { field: field, value: value });
},

L'objet enfant capture et réédite, mais prend d'abord soin d'émettre dans le format attendu par le composant parent (il prend l'intégralité de l'objet data.primary car c'est ce qui est défini sur le modèle v)

Enfants

<grandchild
    :personalInformation="modelValue.personalInformation"
    @updateField="UpdateField"
  />
UpdateField({ field, value }) {
  const newVal = this.modelValue;
  newVal.personalInformation[field] = value;
  this.$emit("update:modelValue", newVal);
}

Ensuite, le composant parent recevra et mettra automatiquement à jour l'objet v-model data.primary.

ou , je dois mentionner que vous pouvez toujours utiliser Pinia, la bibliothèque officielle de gestion d'état pour Vue (enregistrer un état dans un composant et lire le même état à partir de n'importe quel autre composant). Il y a certainement une courbe d'apprentissage, mais cela vaut vraiment la peine d'être appris et est conçu pour simplifier ce type de situation.

Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal