iT邦幫忙

2024 iThome 鐵人賽

DAY 22
0
Modern Web

創意前端設計:用 Vue.js 打造 30 個互動實用功能系列 第 22

Day22 Vue.js 動效分類實戰 (13) 極致表單特輯 - 掌控每次提交的反饋魔力

  • 分享至 

  • xImage
  •  

https://ithelp.ithome.com.tw/upload/images/20241006/20124462Gj3YME1k1K.jpg


高效的表單處理與動效反饋設計

你是否曾經在填寫表單時,感覺整個過程有些枯燥乏味?
或是點擊「提交」後遲遲沒有回應,讓人懷疑到底有沒有成功送出?

其實,表單不僅是網站上用來收集資料的工具,它也可以變得生動有趣,甚至為使用者帶來愉快的互動體驗!

今天,我們將探索如何通過 Vue.js 打造一個不僅高效、還能帶來豐富視覺反饋的表單系統。
透過一些簡單的動效和互動設計,我們可以讓用戶在每次點擊中,都感受到表單的「生命力」。

這篇文章將帶你逐步了解如何在表單處理中融入動效,讓每次操作都變得有趣又直觀。


img

設計核心概念

表單設計不僅僅是輸入框與提交按鈕的組合,還應考慮到以下幾個方面:

  1. 視覺反饋
    當用戶與表單進行交互時,界面應即時反應,例如焦點狀態、錯誤提示等,這樣可以增加用戶的參與感,讓他們感覺到每次操作都有相應的回應。

  2. 互動性設計
    表單中的每一個元素應能夠動態改變,根據用戶的行為(如點擊、焦點、輸入錯誤)展示出不同的視覺變化,這樣可以讓表單更加有趣並避免過於靜態。

  3. 可重用性
    一個好的元件應該具備足夠的靈活性,可以在不同場景中重用。因此,元件的封裝和參數化設計非常重要。


表單核心實作:父元件設計

首先,我們從父元件開始,這裡我們使用 Vue.js 的 shallowRef 來管理表單的狀態與動效。

  • 主要程式碼
<script lang="ts" setup>
import { shallowRef } from "vue";
import InputField from "../components/PinkInput.vue";

// pinkboxTransform 控制表單視圖的左右平移動效
const pinkboxTransform = shallowRef<string>("translateX(0%)");

// 控制登入與註冊視圖顯示
const isSigninVisible = shallowRef<boolean>(true);
const isSignupVisible = shallowRef<boolean>(false);
const isValidate = shallowRef<boolean>(false);

// 表單輸入的帳號與密碼
const username = shallowRef<string>("");
const password = shallowRef<string>("");

// 切換登入與註冊視圖
const switchView = (view: "signin" | "signup") => {
  if (view === "signup") {
    pinkboxTransform.value = "translateX(80%)";
    isSigninVisible.value = false;
    isSignupVisible.value = true;
    return;
  }
  pinkboxTransform.value = "translateX(0%)";
  isSigninVisible.value = true;
  isSignupVisible.value = false;
};
</script>

https://ithelp.ithome.com.tw/upload/images/20241006/20124462f3WJhN96gI.png

  • 關鍵功能:
  1. 動效反饋
    pinkboxTransform 是一個 shallowRef,用來控制表單視圖的平移動畫,讓使用者在切換登入和註冊表單時有流暢的過渡效果。這樣的動畫不僅增強了視覺效果,還提供了一種自然的過渡感。

  2. 動態視圖切換
    isSigninVisibleisSignupVisible 分別控制登入和註冊表單的顯示狀態,根據使用者的選擇來切換不同的表單視圖,避免靜態的畫面,提升互動性。

  3. 表單驗證
    isValidate 用來檢查使用者輸入是否正確,這裡可以加上驗證邏輯,並根據檢查結果展示錯誤提示。這樣即時的反饋能讓使用者更快地知道自己輸入的內容是否有誤。


技術細節解析

img

讓我們從技術細節的角度逐步解析這段程式碼,補充一些關鍵點與原理。

1. 使用 shallowRef 管理狀態

在這段程式碼中,我們使用了 shallowRef 來管理 Vue 3 中的狀態變量。
shallowRef 是 Vue 的一種響應式狀態管理方法,它能夠在變量改變時觸發 Vue 組件的重新渲染,但不會對內部的嵌套對象進行深度觀察。

  • 為什麼選擇 shallowRef
    • 由於這些狀態變量(例如 pinkboxTransformisSigninVisible 等)都是原始數據類型(如 stringboolean),所以不需要深度觀察它們的屬性變化,因此 shallowRef 是一個高效的選擇,避免了不必要的性能消耗。
const pinkboxTransform = shallowRef<string>("translateX(0%)");
const isSigninVisible = shallowRef<boolean>(true);
const isSignupVisible = shallowRef<boolean>(false);
const isValidate = shallowRef<boolean>(false);

2. 動態效果控制:pinkboxTransform

這個變量 pinkboxTransform 用來控制表單視圖的左右平移動畫,它保存的是一個 translateX 的 CSS 值。
在頁面中,表單會根據 translateX 的值平滑地從一個位置滑動到另一個位置,實現視圖之間的切換。

  • 如何實現動畫?
    • 當使用者點擊登入或註冊按鈕時,我們會動態改變 pinkboxTransform 的值。
    • 例如,當用戶切換到註冊視圖時,pinkboxTransform 會設置為 "translateX(80%)",這會讓表單框向右滑動,顯示註冊視圖。
    • 這樣的 CSS 動畫可以通過 transition 屬性平滑地過渡,讓切換過程看起來更加自然。
const pinkboxTransform = shallowRef<string>("translateX(0%)");

3. 表單顯示控制:isSigninVisibleisSignupVisible

這兩個變量用來分別控制登入和註冊表單的顯示。當用戶點擊切換視圖時,通過設置這兩個布爾值,我們可以在 DOM 中隱藏或顯示對應的表單區塊。

  • 為什麼不直接在模板中切換表單?
    • 使用這些狀態變量可以更加靈活地控制視圖切換,而不需要重新渲染整個模板。這樣的做法有助於提升性能,尤其是當表單內容變得複雜時,我們可以只對顯示/隱藏進行簡單操作,避免頻繁的 DOM 變更。
const isSigninVisible = shallowRef<boolean>(true);
const isSignupVisible = shallowRef<boolean>(false);

4. 表單驗證控制:isValidate

isValidate 用來檢查用戶輸入的帳號與密碼是否正確。當用戶點擊登入按鈕時,如果驗證失敗,我們會將 isValidate 設置為 true,並且在視圖中顯示相應的錯誤提示。

  • 表單驗證的邏輯
    • 在這個實例中,我們將驗證邏輯簡化成了一個布爾變量。根據實際需求,這個驗證邏輯可以擴展為更多的條件判斷,例如判斷是否輸入了正確格式的帳號和密碼,或者進行伺服器端的驗證回應。
const isValidate = shallowRef<boolean>(false);

5. 切換視圖的核心邏輯:switchView 方法

這個方法負責在登入與註冊表單之間切換。根據傳入的參數,它會更新 pinkboxTransform 的值,並設置 isSigninVisibleisSignupVisible,從而動態切換不同的視圖。

  • 為什麼需要這個方法?
    • 通過將視圖切換邏輯封裝在這個方法中,我們可以輕鬆地在不同場景下進行調用,無論是點擊按鈕、提交表單,還是其他觸發條件,都能靈活控制。
    • 此外,這樣的封裝可以使程式碼保持應用邏輯的清晰性。
const switchView = (view: "signin" | "signup") => {
  if (view === "signup") {
    pinkboxTransform.value = "translateX(80%)";
    isSigninVisible.value = false;
    isSignupVisible.value = true;
    return;
  }
  pinkboxTransform.value = "translateX(0%)";
  isSigninVisible.value = true;
  isSignupVisible.value = false;
};

6. 管理表單輸入:usernamepassword

這兩個變量用來存儲用戶輸入的帳號和密碼。這些數據將通過表單元件 InputField 的雙向綁定機制實現實時更新。

  • 為什麼使用 shallowRef
    • 和其他狀態變量一樣,usernamepassword 也是基本數據類型,我們使用 shallowRef 來監控其變化,這樣當用戶輸入帳號或密碼時,Vue 會自動觸發相應的更新,保持響應式狀態。
const username = shallowRef<string>("");
const password = shallowRef<string>("");

表單核心實作:input 子元件設計

https://ithelp.ithome.com.tw/upload/images/20241006/20124462f4ESaxWFb9.png

接下來,我們要深入了解自訂表單輸入元件 PinkInput.vue
這個元件的設計目標是讓表單不僅僅停留在靜態的輸入框層面,而是通過視覺上的即時反饋,讓使用者在每次操作時感受到互動的流暢性與精緻感。

程式碼解析:

<script lang="ts" setup>
import { shallowRef } from "vue";

// 定義 props 接收來自父元件的數據
const props = defineProps({
  label: {
    type: String,
    required: true,
  },
  type: {
    type: String,
    required: true,
    default: "text",
  },
  modelValue: {
    type: String,
    default: "",
  },
  inputId: {
    type: String,
    required: true,
  },
  isLabelRed: {
    type: Boolean,
    default: false, // 控制 label 的顏色
  },
});

// 定義 emits 事件,雙向綁定
const emit = defineEmits(["update:modelValue"]);
const inputValue = shallowRef(props.modelValue);
const isFocused = shallowRef(false);

// 讓點擊標籤時輸入框獲得焦點
const focusInput = () => {
  inputRef.value?.focus();
};
</script>

<template>
  <section class="relative">
    <input
      ref="inputRef"
      v-model="inputValue"
      :type="type"
      :id="inputId"
      class="peer block w-full px-3 py-2 rounded-md border border-gray-300 focus:outline-none"
      placeholder=" "
      @focus="isFocused = true"
      @blur="isFocused = false"
    />
    <label
      :for="inputId"
      class="absolute left-3"
      :class="{
        'top-[-10px] scale-75 text-[#cc99a1]': inputValue || isFocused,
        'top-1/2 -translate-y-1/2 scale-100 text-white': !inputValue && !isFocused,
        'text-red-500': isLabelRed
      }"
      @click="focusInput"
    >
      {{ label }}
    </label>
  </section>
</template>

為什麼這樣設計?

  1. 增強互動性: 當使用者與表單互動時,通常希望得到即時的視覺反饋,這能夠讓他們更清晰地感知到當前的操作狀態。因此,我們使用了 focusblur 事件,當輸入框獲得焦點時,標籤會上移並縮小,模擬出一種「內容填充」的視覺效果。這不僅提升了整體的動態感,還讓表單的可讀性更好,避免了使用者的視覺疲勞。

  2. 提高可用性: 在許多表單中,當使用者點擊標籤時,輸入框不會自動獲得焦點。這可能會讓使用者感到操作繁瑣,尤其是在移動端上,這樣的小細節很容易影響整體體驗。為了避免這種情況,我們通過 focusInput() 方法實現了點擊標籤時自動聚焦到對應的輸入框,這樣的設計讓操作更加直觀和順暢。

  3. 錯誤提示與視覺反饋: 我們加入了 isLabelRed 這個 prop 來控制標籤顏色,當表單驗證失敗時,標籤會變為紅色,這是一種直觀的錯誤提示。這樣的視覺反饋設計,可以有效地指引使用者快速糾正錯誤,提升表單的易用性與友好度。

  4. 靈活的元件設計: 這個元件使用了多個 props 來控制它的行為和樣式,讓它能夠在各種不同的表單場景中重複使用。比如,可以自由指定輸入框的類型(文字、密碼等)、標籤內容以及驗證狀態。這樣一來,我們的元件不僅具備高互動性,還有良好的可重用性,適用於不同的需求場景。


本文結語

img

在這篇文章中,我們一起探索了如何通過 Vue.js 來構建一個不僅功能強大,還充滿活力的表單處理系統。
從視覺反饋到互動設計,再到元件的靈活可重用性,我們不僅讓表單變得更好用,還讓它在每次點擊、每次提交時,都能給使用者帶來愉快的互動體驗。

其實,開發者的工作不只是寫程式碼,更是賦予網站「生命力」的過程。
每一個小細節的打磨,無論是流暢的動畫,還是簡潔的表單,都能讓使用者體驗更加與眾不同。

所以,勇敢去嘗試,去創造吧!

你所設計的每一個元件、每一個互動,都是在為使用者帶來更多驚喜與便利。
保持好奇心,繼續探索那些微小但有力的創新,這就是讓你的網站從普通走向卓越的關鍵!


上一篇
Day21 Vue.js 動效分類實戰 (12) 狂野動物幻燈片特輯 - 自訂 Slider,滑出不一樣的驚豔視覺!
下一篇
Day23 Vue.js 動效分類實戰 (14) 骨架屏特輯 - 讓你的網站載入像閃電般快速
系列文
創意前端設計:用 Vue.js 打造 30 個互動實用功能30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言