再次回到最初的Employee.vue程式碼,之前針對互動視窗(modal),曾以此為例介紹前端組件內的資料傳遞,現在再次查看以下程式碼,可以更深刻了解各標籤實際用途,
:modelValue=”showModal”
及@update:modelValue=”showModal = $event”
,這兩個標籤組合成一個同v-model雙向綁定的功能,由:modelValue
接收showModal
資料狀態,並由以@update:modelValue
監聽子組件update事件,以更新showModal
資料狀態,來控制互動視窗的開啟與關閉。:is-edit
及:initial-employee
經由props將資料狀態傳遞給子組件,分別傳遞互動視窗編輯或新增的狀態資訊,及初始的員工資料內容。@submit
則監聽子組件的submit事件,並據以執行handleSubmit
方法,以送出表單填寫的員工資料。<!-- src/views/Employee.vue -->
<template>
<section id="member-settings">
<h1>成員設定</h1>
<!-- 員工資料輸入互動視窗(Modal) -->
<EmployeeModal
:modelValue="showModal"
@update:modelValue="showModal = $event"
:is-edit="isEdit"
:initial-employee="editingEmployee"
@submit="handleSubmit"
/>
</section>
</template>
接著我們馬上打開子組件EmployeeModal.vue,查看互動視窗中的表單,要求網頁使用者填寫的項目,及程式的語法及邏輯控制。
<!-- src/components/Employee/EmployeeModal.vue -->
<!-- Modal外層,v-if綁定modelValue,true:顯示,false:隱藏 -->
<div class="modal-mask" v-if="modelValue">
<!-- Modal標題區 -->
<div class="modal-header">
<h3>{{ modalTitle }}</h3>
</div>
<!-- Modal主要內容區 -->
<div class="modal-body">
<!-- 表單送出事件綁定onOk(),加上.prevent避免瀏覽器預設重新整理 -->
<form @submit.prevent="onOk">
<!-- 姓名表單項目 -->
<div class="form-group">
<label for="name-input">姓名</label>
<input
id="name-input"
type="text"
v-model="form.name"
:class="['form-control', { 'is-invalid': nameState === false }]"
@input="validateName"
required
/>
<div
class="invalid-feedback"
v-if="nameState === false"
>姓名為必填</div>
</div>
<!-- 年齡表單項目 -->
<div class="form-group">
<label for="age-input">年齡</label>
<input
id="age-input"
type="number"
v-model="form.age"
:class="['form-control', { 'is-invalid': ageState === false }]"
@input="validateAge"
min="1"
required
/>
<div
class="invalid-feedback"
v-if="ageState === false"
>年齡需大於 0</div>
</div>
<!-- 電話表單項目 -->
<div class="form-group">
<label for="phone-input">電話</label>
<input
id="phone-input"
type="text"
v-model="form.phone"
:class="['form-control', { 'is-invalid': phoneState === false }]"
@input="validatePhone"
required
/>
<div
class="invalid-feedback"
v-if="phoneState === false"
>請輸入有效手機號碼(09xxxxxxxx)</div>
</div>
<!-- 身分別表單項目 -->
<div class="form-group">
<label for="identity-input">身份別</label>
<select
id="identity-input"
v-model="form.identity"
:class="['form-control', { 'is-invalid': identityState === false }]"
@change="validateIdentity"
required
>
<option value="">請選擇</option>
<option value="FULL">正職</option>
<option value="PART">兼職</option>
</select>
<div
class="invalid-feedback"
v-if="identityState === false"
>請選擇身份別</div>
</div>
<!-- 薪別表單項目 -->
<div class="form-group">
<label for="salary_type-input">薪別</label>
<select
id="salary_type-input"
v-model="form.salary_type"
:class="['form-control', { 'is-invalid': salaryTypeState === false }]"
@change="validateSalaryType"
required
>
<option value="">請選擇</option>
<option value="MONTH">月薪</option>
<option value="HOUR">時薪</option>
</select>
<div
class="invalid-feedback"
v-if="salaryTypeState === false"
>請選擇薪別</div>
</div>
</form>
</div>
<!-- Modal按鈕區 -->
<div class="modal-footer">
<button class="btn btn-secondary" @click="onCancel">取消</button>
<button
class="btn btn-primary"
:disabled="!isFormValid"
@click="onOk"
>送出</button>
</div>
</div>
首先,用v-if="modelValue”
來控制modal的開啟與關閉,modelValue
則取自於父組件的傳值。
通常表單使用<form>
元件,標籤為@submit.prevent=”onOk”
,加上Vue事件修飾符.prevent
,等同於在事件中呼叫event.preventDefault()
。避免執行預設的提交並重新整理頁面的submit行為,而是先執行onOk()
方法,以檢查有無驗證錯誤/格式錯誤後,才送出填寫資料。
在<form>
的裡面,各個<div>
代表各自的表單填寫項目群組,如姓名、年齡、電話、身分別等,包含經典的<label>
及<input>
組合,和<select>
及<option>
組合。
各表單群組中,包括:
<label for=”…”>
及<input id=”…”>
的搭配,以提供點擊標籤聚焦的對應性。v-model
雙向綁定form物件的屬性,如form.name
,使輸入框的值與該屬性自動同步。form-control
,而is-invalid
僅在nameState === false
時套用。validateName()
等驗證方法,更新 nameState
等狀態,確保輸入的內容符合網頁開發者的預設格式要求。required
,乃HTML原生驗證屬性,代表該項目為必填項目。除了表單填寫項目外,另外包括一個提示區塊,v-if控制當各項目驗證狀態為false時(v-if=”nameState === false”
),顯現出提示段落,提醒表單填寫者,該如何填寫以符合預設格式要求。
最後,包含一個按鈕區,取消按鈕,監聽click事件觸發onCancel()
方法,以關閉modal。而送出按鈕,監聽click事件觸發onOk()
方法,並以isFormValid
狀態控制:disabled
屬性,以確保不符合預設格式要求的填寫內容不會被送出。