我對 Vue 比較陌生,正在開發我的第一個專案。我正在努力創建一個包含多個子組件和孫組件的表單。我遇到了一個問題,我需要能夠產生表單的多個副本。因此,我將一些資料屬性上移了 1 級。目前,表單為ApplicationPage.Vue > TheApplication.Vue > PersonalInformation.Vue > BaseInput.Vue。我的問題是我需要透過 TheApplication 發出從 PersonalInformation 到 ApplicationPage 的變更。我很難弄清楚如何處理這種情況。我一直在尋找 Vue2 的解決方案,但沒有找到 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: "" }, }, }, } },
TheApplication.Vue
<personal-information :petOptions="petOptions" :stateOptions='stateOptions' :personalInformation="modelValue.personalInformation" @updateField="UpdateField" />
methods: { UpdateField(field, value) { this.$emit('update:modelValue', {...this.modelValue, [field]: value}) },
個人資訊.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
對於任何不想連結事件發出的人,子對像上都有父對象,它也可用於發出事件。請務必在父級中註冊發射,以避免控制台中出現警告。
在此處呼叫直接父級的 $emit
。
Child.vue
#<input @input="$parent.$emit('custom-event', e.target.value) />
或使用方法:
<input @input="handleInput" />
export default { methods: { handleInput(e) { this.$parent.$emit('custom-event', e.target.value) } } }
由於是父級向祖先發出信號,因此請在此處聲明發射。對於 ,只需使用
defineEmits()
方法來宣告發射。請參閱文件。
Parent.vue
#<Child /> <!-- No need to listen to the event here -->
export default { emits: ['custom-event'] // Register the emits }
如果使用<脚本设置>
<script setup> defineEmits(['custom-event']) // Register the emits </script>
然後在祖父母元件中監聽事件。
GrandParent.vue
<Parent @custom-event="doSomething()" /> <!-- The event is being listened to in the grandparent component -->
P粉8422150062023-11-04 12:19:54
這就是我的做法: codesandbox< /a>
Emits 只接受兩個參數,即發出的名稱和發出的值。如果發出多個值,則必須將這些值作為單一物件發出。 在我的解決方案中,孫組件將欄位名稱和值作為單一物件發出
孫子
<input :value="personalInformation.first_name" @input="onInput('first_name', $event.target.value)" ... >
onInput(field, value) { this.$emit("update-field", { field: field, value: value }); },
子物件捕獲並重新發出,但是首先註意以父組件期望的格式發出(它需要整個data.primary
物件因為這就是被設定為v 模型的內容)
孩子
<grandchild :personalInformation="modelValue.personalInformation" @updateField="UpdateField" />
UpdateField({ field, value }) { const newVal = this.modelValue; newVal.personalInformation[field] = value; this.$emit("update:modelValue", newVal); }
然後父元件會自動接收並更新 v-model data.primary
物件。
或,我必須提到,您始終可以使用Pinia,Vue 的官方狀態管理庫(在一個元件中保存一些狀態,從任何其他元件讀取相同的狀態)。當然有一個學習曲線,但它絕對值得學習,並且正是為了簡化這種類型的情況。