【React hook】手把手學會 Form 表單驗證與 UX 優化全教學

更新 發佈閱讀 30 分鐘
raw-image

在開發 React 時,就發現表格其實是整個網站當中,最常擁有複雜邏輯或驗證的地方。通常表格也會和許多狀態相關,也因此讓設計變得更為複雜。今天這篇文章,就帶大家不使用第三方套件如 Formik,手把手帶你刻 React 的表單驗證。

這篇文章,總共會提到下面三個主題:

  1. 為什麼表單驗證很重要?
  2. 表單驗證的三階段?
  3. 如何優化表單設計?

筆者也會在下面,逐步說明每一個步驟的概念,就讓我們開始吧!


為什麼表單驗證很重要?

在開發前端網頁時,表單是整個開發過程中,非常重要的一塊。因為表單,通常是使用者互動最多的部分,也最容易遇到各種邏輯問題。例如:

  1. 資料型態可能不符合
  2. 需要在使用者輸入錯誤時,提示錯誤並協助更新狀態
  3. 使用者上傳錯誤資訊,導致 Server 收到錯誤資料

甚至在輸入後,也需要進一步至資料庫驗證,還會需要考慮驗證的時間點。例如使用者名稱確認,上述這些情境,都是導致 Form 困難的原因。

也因此,要讓使用者在輸入時,不需額外花費精力理解,但又能讓使用者在輸入錯誤資料時,第一時間獲得反饋,讓使用者有機會,能即時更正輸入的資訊。

前端在表單驗證的角色

對於資料驗證來說,除了在前端進行資料驗證外,也需要在後端進行驗證。主要的原因,是因為前端是能讓使用者透過修改原始碼,讓驗證失效。有興趣的朋友可以參考 Hide JavaScript Code 這篇文章

因此,前端在本身的機制上,無法保證資料的正確性和安全性。


表單驗證的三階段

raw-image

在分析表單驗證時,主要會分成三個階段,分別是:

  1. 當使用者輸入時
  2. 當表格 lost focus 時
  3. 當表格被 Submit 時

每一個部分,都會有各自所遇到的議題,以下是各自常見的議題:

  1. Input:當使用者在輸入時,需要至少讓使用者有輸入正確的時間點。並要在確認輸入資訊無效時,才提供錯誤 feedback。
  2. Lost Focus:我們預設使用者會輸入正確資訊,真的錯誤才提醒。對於應用在未被編輯的表單時,非常有效。
  3. Submit:資料格式可能錯誤,但我們需要在使用者 Submit 後,才根據他的答案提示錯誤;但帶來的缺點,就是 feedback 太晚。

接著,就讓我們一步一步看下去吧!


一、當使用者輸入時

raw-image

A. 如何獲取使用者的輸入內容?

獲取使用者在 Input 的輸入內容,是整個表單驗證的核心。因此也將這個步驟,放在第一個階段。要獲取使用者的輸入內容,主要有兩個方式:

  1. 使用 Event handler 抓取資料
  2. 使用 useRef 獲取 DOM 資料

上述兩個方式,各自帶來的優缺點分別為是:

  1. 使用 Event Handler:優點是能夠做到更細緻的資料驗證,能夠即時給予使用者輸入回饋。但部分情境不需要追蹤每一個輸入值,會導致無意義的重渲染。
  2. 使用 useRef:能夠精簡地獲得資料驗證,但通常僅會使用在上傳(Submit)資料時。因為他需要 Callback,才能觸發當時在 DOM 上的資料狀態;缺點則是無法做到較細緻即時輸入驗證。

1.Event Handler 的寫法

在使用之前,需要提醒每一次修改 Input,例如輸入或刪除,都會觸發 React 元件的 re-render。在下列步驟中,利用每一次改變 Input 值時,會呼叫 Input 屬性的 onChange,讓新的值能夠更新至 enteredInput。

具體步驟如下:

  1. 使用 Handler 抓取當前的 event
  2. 使用 event.target.value 抓到 input 的值
  3. 使用 setEnteredInput 更新輸入值
  4. 將 enteredInput 使用於資料驗證
const [enteredInput, setEnteredInput] = useState("");

const submitHandler = (event) => {
// submit data...
};

const inputChangeHandler = (event) => {
setEnteredInput(event.target.value);
};

<form onSubmit={submitHandler}>
<label htmlFor="name">Your Name</label>
<input type="text" id="name" onChange={inputChangeHandler} />
</form>

其中,label 的屬性 htmlFor,會自動指向相同 id 的 input。因此若點擊 Label 的字,就會自動 Focus name 這個 Input。


2.useRef 的寫法

useRef 的概念更像是快照(snapshot),在特定 Callback 被呼叫時,就可以擷取被 useRef 監聽的元件。而 useRef 會擷取整個被監聽元件的 DOM,也因此可以獲取其中的 value。

具體步驟如下:

  1. 使用 useRef 設定監聽器
  2. 將監聽器傳入 Input 的屬性 ref
  3. 在 Submit 時使用監聽到的資料 inputRef
  4. 從 inputRef.current.value 獲取 Input 的值
const inputRef = useRef();

const submitHandler = (event) => {
submitDataHandler(inputRef.current.value);
};

return (
<form onSubmit={submitHandler}>
<label htmlFor="name">Your Name</label>
<input type="text" id="name" ref={inputRef} />
</form>
);

二、當表格 Lost focus 時

raw-image

當使用者輸入完表格,準備離開當前輸入框時,就可以做第一次的驗證,可以避免使用者最後一刻,才收到修改的提示或無法提交。

要執行 Lost Focus 時的驗證,需要有四個步驟:

  1. 檢驗輸入資料的正確性
  2. 檢驗表格是否輸入過
  3. 顯示錯誤提示訊息
  4. 即時驗證與更新訊息

A. 檢驗輸入資料的正確性

最常見的莫過於姓名與 Email 的驗證,以下簡單提供驗證的方式,當然直接請 ChatGPT 協助你寫正規表達式,整體的速度會更快。

這個階段,是確保從 state 抓到的資料,可以明確知道當前的資料是否符合驗證,若符合驗證,就可以提交;若不符合驗證,就會跳出修改的提示訊息。

為空值 input 進行驗證

透過 trim 去掉頭尾的空白,並確保長度大於 0。

const nameValidation = (name) => {
const isNameInputValid = name.trim().length !== 0;
return isNameInputValid;
};

為 Email 進行驗證:

const emailValidation = (email) => {
const re = /^(([^<>()\\[\\]\\\\.,;:\\s@"]+(\\.[^<>()\\[\\]\\\\.,;:\\s@"]+)*)|(".+"))@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\])|(([a-zA-Z\\-0-9]+\\.)+[a-zA-Z]{2,}))$/;
return re.test(String(email).toLowerCase());
}

B. 檢驗表格是否曾輸入過

除了驗證資料是否正確外,另一個重點,就是確認使用者是否碰觸過輸入框。因此,我們就需要用到 DOM 提供的內建方法 onBlur,來監測當使用者 Lost Focus 時,需要執行的 callback function。

const [enteredNameInput, setEnteredNameInput] = useState("");
const [isNameInputTouched, setIsNameInputTouched] = useState(false);

// DEFINE Callback function
const inputNameBlurHandler = (event) => {
setIsNameInputTouched(true);
};

// CALLBACK WHEN INPUT LOST FOCUS
<input onBlur={inputBlurHandler} />

C. 顯示錯誤提示訊息

接著,我們就要使用前面提到的驗證資料正確性,以及確認表格是否被輸入過,卻評估是否需要顯示錯誤訊息。

以下,我們就拿名稱輸入的表格,進行錯誤訊息的提示示範。而錯誤訊息之所以要使用 isNameInputTouched!isNameInputValid (意指驗證無效),是因為我們相信使用者,「一開始是會輸入正確資訊」,所以當 Touched 被預設為 false 時,就不會出現 Error。

直到使用者確定有 Lost Focus 的行為,但卻又沒有通過驗證時,再顯示錯誤訊息才適合適的時機。

假設我們是使用者,也不希望一開始,就被通知輸入無效資訊吧!

使用 CSS Class,控制錯誤訊息顯示

// VALIDATE nameInput is INVALID
const nameInputIsInvalid = isNameInputTouched && !isNameInputValid;

// SET INPUT CLASS WITH ERROR STATE
const nameInputClass = nameInputIsInvalid
? "form-control invalid"
: "form-control";

// DISPLAY error message WHEN INPUT IS INVALID
<div className={nameInputClass}>
<label htmlFor="name">Your Name</label>
<input
value={enteredNameInput}
type="text"
id="name"
onBlur={inputNameBlurHandler}
onChange={inputNameChangeHandler}
/>
{nameInputIsInvalid && <p className="error-text">Name must not be empty.</p>}
</div>;

D. 即時驗證與更新訊息

當使用者更正為正確內容時,只要一符合標準,我們就將 Error Message 移除。讓使用者知道,他已經正確達到要求。

這裡要再重新強調一個概念,每當我們使用 Event Listener 監控 Input 的值時,每一次觸發 Callback function,都會讓整個元件重新渲染。因此,在第三階段的「顯示錯誤提示訊息」中,nameInputIsInvalid 每一次都會重新聲明,因此每鍵入一次,就會重新驗證一次。也因此 nameInputIsInvalid 的值,也都會根據每一次輸入,而重新驗證。

除此之外,我們也能夠透過狀態管理,讓整個表格的遞交按鈕,能夠暫時被關閉。

利用驗證,暫時關閉提交(Submit)按鈕

raw-image

以下就以 Email 和名稱的表格驗證,來示範如何達成。我們先個別設定 Email 和名稱的 Input 的 touched 狀態;接著,撰寫 Email 和名稱的驗證;再來,個別驗證輸入的有效性。最後,才是驗證整個表格的狀態。

const [enteredEmailInput, setEnteredEmailInput] = useState("");
const [isEmailInputTouched, setIsEmailInputTouched] = useState(false);

const [enteredNameInput, setEnteredNameInput] = useState("");
const [isNameInputTouched, setIsNameInputTouched] = useState(false);

const checkEmail = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;
const isEmailInputValid = checkEmail.test(enteredEmailInput);
const isNameInputValid = enteredNameInput.trim().length !== 0;

const nameInputIsInvalid = isNameInputTouched && !isNameInputValid;
const emailInputIsInvalid = isEmailInputTouched && !isEmailInputValid;

// APPLY FOR MANAGING BUTTON STATUS
const isFormValid = isNameInputValid && isEmailInputValid;

// JSX SUBMIT BUTTON
<div className="form-actions">
<button disabled={!isFormValid}>Submit</button>
</div>;

三、當表格被 Submit 時

raw-image

當使用者輸入完表格(或輸入錯誤的資訊時),仍然要在遞交時,再進行一次 Submit,確保推去後端的資料沒問題。

要執行 Submit 驗證時,有兩個步驟需要被考慮到:

  1. 多表格驗證
  2. 重置表格

A. 多表格驗證

若我們有在前面階段,就使用多表格的確認,就可以同樣在 Submit 時,使用表格驗證來做最後一層確認。我們使用上一個「暫時關閉提交按鈕」的案例來延伸。我們可以在處理提交的 SubmitHandler 中,使用判斷式來決定,是否要執行此次的 Submit 行為。

const submitHandler = (event) => {
event.preventDefault();

// DEFAULT USER HAS TOUCHED INPUT DUE TO CONFIRMATION
setIsFormTouched(true);

// COULD NOT SUBMIT IF FORM IS NOT VALID
if (!isFormValid) {
// DROP OUT DUE TO return
return;
}

fetch(url, { method: "POST", body: ...})
};

其中,我們先使用 event.preventDefault();,來避免 Submit 後會重新 Reload 畫面的預設狀態。接著,為了讓錯誤能跳轉出來,此處我們將 setIsFormTouched 設定為 true,可以視為用戶已經完成編輯,因此一定會接觸過表格。

再來,就是使用一個簡單的判斷式 !isFormValid,來確定表單已經完成驗證,若沒有,就會直接跳出函式,後面的 fetch 遞交也就不會執行。


B. 重置表格

有時我們希望輸入後,表格可以重置,讓使用者可以繼續輸入下一次的內容。這時可以使用兩個方式:

  1. 重置 State
  2. 操控 useRef

以下個別示範各自的用法。

1.重置 State

// STATE UPDATE
const [enteredInput, setEnteredInput] = useState("");
const [isFormTouched, setIsFormTouched] = useState("");

const submitHandler = (event) => {
event.preventDefault();

...

setEnteredInput("");
setIsFormTouched(false);
};

<input value={enteredInput} />

2.操控 useRef

// useRef UPDATE | NOT RECOMMAND!
const [isFormTouched, setIsFormTouched] = useState("");

const inputRef = useRef();

const submitHandler = (event) => {
event.preventDefault();

inputRef.current.value = "";
setIsFormTouched(false);
};

<input ref={inputRef} />

第二個方式,是使用 useRef 時,又需要重置 Input 的值時使用。因為會直接操縱到 DOM,因此通常不建議如此使用。如果有重置 Input 的需求,還是盡量使用 useState 進行更新。


優化表單設計

前面敘述的寫法,如果超過一個表格時,就會發現重複的程式碼非常多;更麻煩的是,會讓個別元件變得肥大。試想,如果上述的程式碼需要檢驗 7~8 個表格,雖然結構簡單且易懂,但就容易讓程式碼變得冗長。

因此,若要優化整個元件設計,有兩個常見的改善方式:

  1. 拆分個別元件
  2. 使用 Custom hook
  3. 使用第三方套件

A. 拆分個別元件

這個概念也非常直觀,我們僅需要將每一個 Input 都轉換成一個獨立的元件,並在各自的元件中進行驗證即可。

然而,這個架構會導致一個問題:在進行完整全表單的驗證時,就需要將各自的參數全部傳出,這會導致父層元件多了非常多參數傳遞。

這個方式僅建議使用在 2~3 個 Input 時使用。


B. 使用 Custom hook

一開始的時候,確實很難判斷是否要使用 custom hook,但在開始後發現有重複的地方,就可以考慮重新使用 custom hook 來抽象化。

透過抽離所有重複的程式碼,我們也將原先特定的 nameInput 等,調整成 enteredValue 這樣通用的變數。

// in src/hooks/use-input.js

import { useState } from "react";

// MUST start with "use"
const useInput = (validationFunc) => {
const [enteredValue, setEnteredValue] = useState("");
const [isTouched, setIsTouched] = useState(false);

const isValueValid = validationFunc(enteredValue);
const hasError = isTouched && !isValueValid; // false and true

const valueChangeHandler = (event) => {
setEnteredValue(event.target.value);
};

const valueBlurHandler = (event) => {
setIsTouched(true);
};

const resetValueHandler = () => {
setEnteredValue("");
setIsTouched(false);
};

const inputClassHandler = () => {
const className = hasError ? "form-control invalid" : "form-control";
return className;
};

return {
value: enteredValue,
hasError: hasError,
isValueValid: isValueValid,
inputClass: inputClassHandler(),
reset: resetValueHandler,
valueChangeHandler,
valueBlurHandler,
};
};

export default useInput;

Custom hook 實際案例應用:

在我們欲使用表單的元件中,引入 custom hook 來生成表單驗證。此處,我們使用了 name 和 email 這兩個 Input,設計一張表單來驗證。

透過傳入 validation function,我們可以輕易生成個別表單的各種狀態。透過生成的狀態,就可以在想要管理的 Input 中,傳入各種所需的參數。

import useInput from "../hooks/use-input";

const SimpleForm = (props) => {
const emailValidation = (email) => {
const checkEmailRegExp = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;
const isEmailInputValid = checkEmailRegExp.test(email);
return isEmailInputValid;
};

const nameValidation = (name) => {
const isNameInputValid = name.trim().length !== 0;
return isNameInputValid;
};

const {
value: emailInput,
hasError: emailInputHasError,
isValueValid: isEmailInputValid,
inputClass: emailInputClass,
reset: resetEmailInput,
valueChangeHandler: emailInputChangeHandler,
valueBlurHandler: emailInputBlurHandler,
} = useInput(emailValidation);

const {
value: nameInput,
hasError: nameInputHasError,
isValueValid: isNameInputValid,
inputClass: nameInputClass,
reset: resetNameInput,
valueChangeHandler: nameInputChangeHandler,
valueBlurHandler: nameInputBlurHandler,
} = useInput(nameValidation);

// IF INPUT HAS ERROR, THEN SET BUTTON DISABLE
const isFormValid = !nameInputHasError && !emailInputHasError;

const submitHandler = (event) => {
event.preventDefault();

// CHECK WHETHER EITHER INPUT IS INVALID, THEN DROPOUT
if (!isNameInputValid || !isEmailInputValid) {
return;
}

resetEmailInput();
resetNameInput();

console.log(emailInput);
console.log(nameInput);
};

return (
<form onSubmit={submitHandler}>
<div className={emailInputClass}>
<label htmlFor="email">Your Email</label>
<input
value={emailInput}
type="email"
id="email"
onBlur={emailInputBlurHandler}
onChange={emailInputChangeHandler}
/>
{emailInputHasError && (
<p className="error-text">Email format is not allowed.</p>
)}
</div>
<div className={nameInputClass}>
<label htmlFor="name">Your Name</label>
<input
value={nameInput}
type="text"
id="name"
onBlur={nameInputBlurHandler}
onChange={nameInputChangeHandler}
/>
{nameInputHasError && (
<p className="error-text">Name must not be empty.</p>
)}
</div>
<div className="form-actions">
<button disabled={!isFormValid}>Submit</button>
</div>
</form>
);
};



C.使用第三方套件

除了自己實現表單驗證外,也有設計好的套件可以使用。例如 React 生態系所使用的 Formik,就是一個很完善的表單套件。可以根據自己的需求取用。


結論

表單設計,一直是前端處理很複雜的一塊;但複雜的並非程式,而是在輸入表單時,能否給予使用者完整、友善的體驗,更讓使用者知道,要如何更改輸入才能通過驗證。

因此在設計表單時,除了確認資料的驗證外,瞭解使用者的輸入習慣,甚至要考量到極端情境或資安問題,才能讓使用者在滿足個人的使用需求外,不需要擔心個人的資料被竊取。

若有有興趣或相關經驗的讀者,也歡迎留言一起分享交流!


參考資料


留言
avatar-img
學.誌|Chris Kang的沙龍
7.5K會員
14內容數
此處作為整理前端(Frontend)和相關的 HTML、CSS、JavaScript、React 等前端觀念與技巧,全部都會收錄在這個專題之中。同時也會將相關的技術與反思記錄在此,歡迎各位讀者互相交流。
2024/04/08
本文帶你深入探索 TypeScript 中的 satisfies 特性,能幫助你實現精確的型別推導與型別檢查。透過實際案例,展示如何使用 satisfies 提升代碼的型別安全與程式碼的整潔,是每位 TypeScript 開發者不可或缺的知識。
Thumbnail
2024/04/08
本文帶你深入探索 TypeScript 中的 satisfies 特性,能幫助你實現精確的型別推導與型別檢查。透過實際案例,展示如何使用 satisfies 提升代碼的型別安全與程式碼的整潔,是每位 TypeScript 開發者不可或缺的知識。
Thumbnail
2024/03/26
本文介紹 TypeScript 常遇到的混合型別,以及如何透過五種型別防禦(Type Guard)來解決。涵蓋了使用型別斷言、型別謂詞、in 運算子、typeof 運算子以及 instanceof 運算子這幾種方式。透過本文的學習,能夠更好地運用 TypeScript 進行程式碼開發。
Thumbnail
2024/03/26
本文介紹 TypeScript 常遇到的混合型別,以及如何透過五種型別防禦(Type Guard)來解決。涵蓋了使用型別斷言、型別謂詞、in 運算子、typeof 運算子以及 instanceof 運算子這幾種方式。透過本文的學習,能夠更好地運用 TypeScript 進行程式碼開發。
Thumbnail
2024/02/04
本文將深入探討鏈表的核心概念,使用 JavaScript 來說明如何實現和操作鏈表(Linked List),包括 append、prepend、remove、find 和 reverse 等五大方法。
Thumbnail
2024/02/04
本文將深入探討鏈表的核心概念,使用 JavaScript 來說明如何實現和操作鏈表(Linked List),包括 append、prepend、remove、find 和 reverse 等五大方法。
Thumbnail
看更多
你可能也想看
Thumbnail
在 vocus 與你一起探索內容、發掘靈感的路上,我們又將啟動新的冒險——vocus App 正式推出! 現在起,你可以在 iOS App Store 下載全新上架的 vocus App。 無論是在通勤路上、日常空檔,或一天結束後的放鬆時刻,都能自在沈浸在內容宇宙中。
Thumbnail
在 vocus 與你一起探索內容、發掘靈感的路上,我們又將啟動新的冒險——vocus App 正式推出! 現在起,你可以在 iOS App Store 下載全新上架的 vocus App。 無論是在通勤路上、日常空檔,或一天結束後的放鬆時刻,都能自在沈浸在內容宇宙中。
Thumbnail
vocus 慶祝推出 App,舉辦 2026 全站慶。推出精選內容與數位商品折扣,訂單免費與紅包抽獎、新註冊會員專屬活動、Boba Boost 贊助抽紅包,以及全站徵文,並邀請你一起來回顧過去的一年, vocus 與創作者共同留下了哪些精彩創作。
Thumbnail
vocus 慶祝推出 App,舉辦 2026 全站慶。推出精選內容與數位商品折扣,訂單免費與紅包抽獎、新註冊會員專屬活動、Boba Boost 贊助抽紅包,以及全站徵文,並邀請你一起來回顧過去的一年, vocus 與創作者共同留下了哪些精彩創作。
Thumbnail
在之前【如何進行設計交付?做自己看得懂的檢核表、不要害怕看網頁原始碼…】那篇文中有提到,交付時可製作一份交付Checklist,這個概念也可以套用在設計過程中! 最近發現一個超實用的工具「Checklist Design」,Checklist Design 提供各種UI設計的確認清單,包括一些你可
Thumbnail
在之前【如何進行設計交付?做自己看得懂的檢核表、不要害怕看網頁原始碼…】那篇文中有提到,交付時可製作一份交付Checklist,這個概念也可以套用在設計過程中! 最近發現一個超實用的工具「Checklist Design」,Checklist Design 提供各種UI設計的確認清單,包括一些你可
Thumbnail
步驟二:表單細節修正 我們延續上一篇EP1,本篇文章要來微調表單上的一些功能,使其更符合操作: 我們發現發文單位、公文類別、會簽單位、審核單位這四個欄位尚未設定正確...
Thumbnail
步驟二:表單細節修正 我們延續上一篇EP1,本篇文章要來微調表單上的一些功能,使其更符合操作: 我們發現發文單位、公文類別、會簽單位、審核單位這四個欄位尚未設定正確...
Thumbnail
這次的 Frontend Mentor challenge 是新手村最後一個挑戰 ▶ Intro component with sign up form 網頁,使用 jQuery validation plugin。
Thumbnail
這次的 Frontend Mentor challenge 是新手村最後一個挑戰 ▶ Intro component with sign up form 網頁,使用 jQuery validation plugin。
Thumbnail
React 表單驗證是一種技術與使用者體驗的設計,讓使用者能夠即時檢查輸入的資料並修正,提升使用者的使用體驗,並確保資料的正確性。
Thumbnail
React 表單驗證是一種技術與使用者體驗的設計,讓使用者能夠即時檢查輸入的資料並修正,提升使用者的使用體驗,並確保資料的正確性。
Thumbnail
Input 輸入元件一直是各大網站必備的元素,這篇會分成文字輸入 Text、按鈕 Button、互動元件 Modal、下拉式選單 Dropdown List、滑桿 Slider、選擇器 Picker 這六種常見介面元件,來記錄我在平台工作時遇到的 UI 元件,作為未來產品開發的資料庫。
Thumbnail
Input 輸入元件一直是各大網站必備的元素,這篇會分成文字輸入 Text、按鈕 Button、互動元件 Modal、下拉式選單 Dropdown List、滑桿 Slider、選擇器 Picker 這六種常見介面元件,來記錄我在平台工作時遇到的 UI 元件,作為未來產品開發的資料庫。
Thumbnail
除了常見的下拉式選單,我們還有其他的驗證機制可以使用。今天就來看看怎麼設定數值、文字、日期的資料驗證吧!
Thumbnail
除了常見的下拉式選單,我們還有其他的驗證機制可以使用。今天就來看看怎麼設定數值、文字、日期的資料驗證吧!
Thumbnail
常見的下拉式選單怎麼做?資料驗證又是什麼?資料驗證是個「驗證資料是否符合某條件的機制」,我們通常會用它來避免別人輸入無效的值,減少錯誤的發生。來看看吧!
Thumbnail
常見的下拉式選單怎麼做?資料驗證又是什麼?資料驗證是個「驗證資料是否符合某條件的機制」,我們通常會用它來避免別人輸入無效的值,減少錯誤的發生。來看看吧!
Thumbnail
之前一直沒有寫相關的作業心得筆記,一方面是覺得很熟練難度不高所以就很懶惰...但進入到學期2-2後,光是S2的製作電影清單,突然感覺難度一下提升超級多,很多內容不是一次兩次就能夠記起來且熟悉,而且邏輯程式方面的量也上升到百行才發現真的很難一下吸收,所以決定開始來寫學習、作業、技術相關筆記來加深自己的
Thumbnail
之前一直沒有寫相關的作業心得筆記,一方面是覺得很熟練難度不高所以就很懶惰...但進入到學期2-2後,光是S2的製作電影清單,突然感覺難度一下提升超級多,很多內容不是一次兩次就能夠記起來且熟悉,而且邏輯程式方面的量也上升到百行才發現真的很難一下吸收,所以決定開始來寫學習、作業、技術相關筆記來加深自己的
Thumbnail
輸入畫面 為什麼要做驗證? 因為作為設計者,永遠不該預設使用者會乖乖照設計者的意思輸入。
Thumbnail
輸入畫面 為什麼要做驗證? 因為作為設計者,永遠不該預設使用者會乖乖照設計者的意思輸入。
Thumbnail
UX文案是設計師們操作情境很好的工具,可以減少用戶認知負擔,讓介面簡單易懂。但我看過許多後台介面的Placeholder文案似乎是亂寫的? 為什麼想寫這個題目? 比起光鮮亮麗的前台介面流程,一般營運管理介面(俗稱後台)經常淪為配角,常被認為是「有空再來談怎麼優化」,而所謂的後台優化常常意味著追加功能
Thumbnail
UX文案是設計師們操作情境很好的工具,可以減少用戶認知負擔,讓介面簡單易懂。但我看過許多後台介面的Placeholder文案似乎是亂寫的? 為什麼想寫這個題目? 比起光鮮亮麗的前台介面流程,一般營運管理介面(俗稱後台)經常淪為配角,常被認為是「有空再來談怎麼優化」,而所謂的後台優化常常意味著追加功能
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News