Maison > Questions et réponses > le corps du texte
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粉0378809052023-11-04 14:55:06
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.
Appelez le parent direct $emit
ici.
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) } } }
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>
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粉8422150062023-11-04 12:19:54
Voici comment je procède : codesandbox< /a>
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.