iT邦幫忙

2025 iThome 鐵人賽

DAY 24
0

再次回到最初的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,使輸入框的值與該屬性自動同步。
  • 動態綁定class屬性,採陣列與物件綁定組合,常態套用form-control,而is-invalid僅在nameState === false時套用。
  • 監聽input或change事件,即時進行validateName()等驗證方法,更新 nameState等狀態,確保輸入的內容符合網頁開發者的預設格式要求。
  • required,乃HTML原生驗證屬性,代表該項目為必填項目。

除了表單填寫項目外,另外包括一個提示區塊,v-if控制當各項目驗證狀態為false時(v-if=”nameState === false”),顯現出提示段落,提醒表單填寫者,該如何填寫以符合預設格式要求。

最後,包含一個按鈕區,取消按鈕,監聽click事件觸發onCancel()方法,以關閉modal。而送出按鈕,監聽click事件觸發onOk()方法,並以isFormValid狀態控制:disabled屬性,以確保不符合預設格式要求的填寫內容不會被送出。


上一篇
Day 23: Vue的v-model雙向綁定
下一篇
Day 25: Vue表單前端驗證及正則表達式(regular expression)
系列文
從零打造網頁系統:非資訊人也能完成的全端專題實作29
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言