你是否曾經在填寫表單時,感覺整個過程有些枯燥乏味?
或是點擊「提交」後遲遲沒有回應,讓人懷疑到底有沒有成功送出?
其實,表單不僅是網站上用來收集資料的工具,它也可以變得生動有趣,甚至為使用者帶來愉快的互動體驗!
今天,我們將探索如何通過 Vue.js 打造一個不僅高效、還能帶來豐富視覺反饋的表單系統。
透過一些簡單的動效和互動設計,我們可以讓用戶在每次點擊中,都感受到表單的「生命力」。
這篇文章將帶你逐步了解如何在表單處理中融入動效,讓每次操作都變得有趣又直觀。
表單設計不僅僅是輸入框與提交按鈕的組合,還應考慮到以下幾個方面:
視覺反饋:
當用戶與表單進行交互時,界面應即時反應,例如焦點狀態、錯誤提示等,這樣可以增加用戶的參與感,讓他們感覺到每次操作都有相應的回應。
互動性設計:
表單中的每一個元素應能夠動態改變,根據用戶的行為(如點擊、焦點、輸入錯誤)展示出不同的視覺變化,這樣可以讓表單更加有趣並避免過於靜態。
可重用性:
一個好的元件應該具備足夠的靈活性,可以在不同場景中重用。因此,元件的封裝和參數化設計非常重要。
首先,我們從父元件開始,這裡我們使用 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>
動效反饋:pinkboxTransform
是一個 shallowRef
,用來控制表單視圖的平移動畫,讓使用者在切換登入和註冊表單時有流暢的過渡效果。這樣的動畫不僅增強了視覺效果,還提供了一種自然的過渡感。
動態視圖切換:isSigninVisible
和 isSignupVisible
分別控制登入和註冊表單的顯示狀態,根據使用者的選擇來切換不同的表單視圖,避免靜態的畫面,提升互動性。
表單驗證:isValidate
用來檢查使用者輸入是否正確,這裡可以加上驗證邏輯,並根據檢查結果展示錯誤提示。這樣即時的反饋能讓使用者更快地知道自己輸入的內容是否有誤。
讓我們從技術細節的角度逐步解析這段程式碼,補充一些關鍵點與原理。
shallowRef
管理狀態在這段程式碼中,我們使用了 shallowRef
來管理 Vue 3 中的狀態變量。shallowRef
是 Vue 的一種響應式狀態管理方法,它能夠在變量改變時觸發 Vue 組件的重新渲染,但不會對內部的嵌套對象進行深度觀察。
shallowRef
?
pinkboxTransform
、isSigninVisible
等)都是原始數據類型(如 string
和 boolean
),所以不需要深度觀察它們的屬性變化,因此 shallowRef
是一個高效的選擇,避免了不必要的性能消耗。const pinkboxTransform = shallowRef<string>("translateX(0%)");
const isSigninVisible = shallowRef<boolean>(true);
const isSignupVisible = shallowRef<boolean>(false);
const isValidate = shallowRef<boolean>(false);
pinkboxTransform
這個變量 pinkboxTransform
用來控制表單視圖的左右平移動畫,它保存的是一個 translateX
的 CSS 值。
在頁面中,表單會根據 translateX
的值平滑地從一個位置滑動到另一個位置,實現視圖之間的切換。
pinkboxTransform
的值。pinkboxTransform
會設置為 "translateX(80%)"
,這會讓表單框向右滑動,顯示註冊視圖。transition
屬性平滑地過渡,讓切換過程看起來更加自然。const pinkboxTransform = shallowRef<string>("translateX(0%)");
isSigninVisible
和 isSignupVisible
這兩個變量用來分別控制登入和註冊表單的顯示。當用戶點擊切換視圖時,通過設置這兩個布爾值,我們可以在 DOM 中隱藏或顯示對應的表單區塊。
const isSigninVisible = shallowRef<boolean>(true);
const isSignupVisible = shallowRef<boolean>(false);
isValidate
isValidate
用來檢查用戶輸入的帳號與密碼是否正確。當用戶點擊登入按鈕時,如果驗證失敗,我們會將 isValidate
設置為 true
,並且在視圖中顯示相應的錯誤提示。
const isValidate = shallowRef<boolean>(false);
switchView
方法這個方法負責在登入與註冊表單之間切換。根據傳入的參數,它會更新 pinkboxTransform
的值,並設置 isSigninVisible
和 isSignupVisible
,從而動態切換不同的視圖。
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;
};
username
和 password
這兩個變量用來存儲用戶輸入的帳號和密碼。這些數據將通過表單元件 InputField
的雙向綁定機制實現實時更新。
shallowRef
?
username
和 password
也是基本數據類型,我們使用 shallowRef
來監控其變化,這樣當用戶輸入帳號或密碼時,Vue 會自動觸發相應的更新,保持響應式狀態。const username = shallowRef<string>("");
const password = shallowRef<string>("");
接下來,我們要深入了解自訂表單輸入元件 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>
增強互動性: 當使用者與表單互動時,通常希望得到即時的視覺反饋,這能夠讓他們更清晰地感知到當前的操作狀態。因此,我們使用了 focus
和 blur
事件,當輸入框獲得焦點時,標籤會上移並縮小,模擬出一種「內容填充」的視覺效果。這不僅提升了整體的動態感,還讓表單的可讀性更好,避免了使用者的視覺疲勞。
提高可用性: 在許多表單中,當使用者點擊標籤時,輸入框不會自動獲得焦點。這可能會讓使用者感到操作繁瑣,尤其是在移動端上,這樣的小細節很容易影響整體體驗。為了避免這種情況,我們通過 focusInput()
方法實現了點擊標籤時自動聚焦到對應的輸入框,這樣的設計讓操作更加直觀和順暢。
錯誤提示與視覺反饋: 我們加入了 isLabelRed
這個 prop
來控制標籤顏色,當表單驗證失敗時,標籤會變為紅色,這是一種直觀的錯誤提示。這樣的視覺反饋設計,可以有效地指引使用者快速糾正錯誤,提升表單的易用性與友好度。
靈活的元件設計: 這個元件使用了多個 props
來控制它的行為和樣式,讓它能夠在各種不同的表單場景中重複使用。比如,可以自由指定輸入框的類型(文字、密碼等)、標籤內容以及驗證狀態。這樣一來,我們的元件不僅具備高互動性,還有良好的可重用性,適用於不同的需求場景。
在這篇文章中,我們一起探索了如何通過 Vue.js 來構建一個不僅功能強大,還充滿活力的表單處理系統。
從視覺反饋到互動設計,再到元件的靈活可重用性,我們不僅讓表單變得更好用,還讓它在每次點擊、每次提交時,都能給使用者帶來愉快的互動體驗。
其實,開發者的工作不只是寫程式碼,更是賦予網站「生命力」的過程。
每一個小細節的打磨,無論是流暢的動畫,還是簡潔的表單,都能讓使用者體驗更加與眾不同。
所以,勇敢去嘗試,去創造吧!
你所設計的每一個元件、每一個互動,都是在為使用者帶來更多驚喜與便利。
保持好奇心,繼續探索那些微小但有力的創新,這就是讓你的網站從普通走向卓越的關鍵!