📅 我們繼續 50 個小項目挑戰!—— FormWave
組件
倉庫地址:https://github.com/SunACong/50-vue-projects
項目預覽地址:https://50-vue-projects.vercel.app/
🎯 組件目標
構建一個美觀、動態的登錄表單,重點在于實現帶有浮動標簽(floating label
)的輸入框體驗,提升交互感知和視覺效果,適合作為任何登錄注冊模塊的基礎模板。
🛠? 技術實現點
- 使用 Vue3 +
<script setup>
編寫響應式邏輯。 - 使用 TailwindCSS 完全控制樣式,特別是浮動文字的動畫。
- 實現
focus
/blur
狀態下標簽文字的動畫浮動效果。 - 使用
v-model
實現雙向綁定,結合focus
狀態精準控制浮動邏輯。
🧱 組件實現
<!-- 🌈 模板部分 Template -->
<template><div class="flex h-screen items-center justify-center bg-gray-800 text-gray-300"><div class="rounded-2xl bg-gray-500/60 p-12 text-center"><h1 class="text-4xl font-bold text-gray-300">Please Login</h1><form><!-- Email 輸入框 --><div class="form-control relative mt-10 border-b-2 border-b-white"><inputclass="peer relative z-10 w-full bg-transparent py-3 text-white focus:border-sky-300 focus:outline-none"type="text"requiredv-model="emailValue"@focus="activeInput = 'email'"@blur="handleBlur('email')" /><label class="pointer-events-none absolute top-4 left-0"><!-- ? 字符級浮動動畫 --><spanv-for="(letter, idx) in 'Email'.split('')":key="idx":class="['inline-block min-w-[5px] text-lg transition-all duration-300','transform-gpu',{'-translate-y-8 text-sky-300':activeInput === 'email' || emailValue,},]":style="{transitionDelay: `${idx * 50}ms`,transitionTimingFunction: 'cubic-bezier(0.68, -0.55, 0.265, 1.55)',}">{{ letter }}</span></label></div><!-- Password 輸入框 --><div class="form-control relative mt-10 border-b-2 border-b-white"><inputclass="peer relative z-10 w-full bg-transparent py-3 text-white focus:border-sky-300 focus:outline-none"type="password"requiredv-model="passwordValue"@focus="activeInput = 'password'"@blur="handleBlur('password')" /><label class="pointer-events-none absolute top-4 left-0"><!-- ? 字符級浮動動畫 --><spanv-for="(letter, idx) in 'Password'.split('')":key="idx":class="['inline-block min-w-[5px] text-lg transition-all duration-300','transform-gpu',{'-translate-y-8 text-sky-300':activeInput === 'password' || passwordValue,},]":style="{transitionDelay: `${idx * 50}ms`,transitionTimingFunction: 'cubic-bezier(0.68, -0.55, 0.265, 1.55)',}">{{ letter }}</span></label></div><!-- 登錄按鈕 --><buttonclass="mt-10 w-full rounded bg-blue-500 px-4 py-2 font-bold hover:bg-blue-600 focus:ring-2 focus:ring-blue-400 focus:outline-none"type="submit">Login</button><p class="mt-10">Don't have an account?<a href="#" class="text-blue-400 hover:underline">Register</a></p></form></div></div>
</template>
🧩 重點效果實現
<!-- ?? 腳本部分 Script -->
<script setup>
import { ref } from 'vue'// 輸入值響應式變量
const emailValue = ref('')
const passwordValue = ref('')// 當前聚焦的輸入項
const activeInput = ref(null)// 失焦邏輯:如果輸入框為空,則取消浮動狀態
const handleBlur = (inputName) => {if ((inputName === 'email' && !emailValue.value) ||(inputName === 'password' && !passwordValue.value)) {activeInput.value = null}
}
</script>
- 標簽浮動是通過
translate-y
配合activeInput
或綁定值來實現的。 - 使用
transition-delay
實現了字符級別的延遲動畫,讓文字一個個浮動。 - 利用
cubic-bezier
定義自定義緩動函數,提升動畫的彈性和自然感。
🎨 TailwindCSS 樣式重點講解
類名 | 作用 |
---|---|
peer / relative z-10 | 確保 input 在 label 之上,供 label 狀態判斷使用 |
-translate-y-8 | 控制文字上浮距離 |
transition-delay | 實現文字一個個浮動的動畫延遲 |
transform-gpu | 使用 GPU 加速動畫,提高性能和流暢度 |
focus:outline-none / focus:ring-2 | 聚焦時視覺反饋 |
min-w-[5px] | 保證字符寬度一致,不會斷行 |
🧾 常量定義 + 組件路由建議
constants/index.js
添加組件預覽常量:
{id: 8,title: 'Form Wave',image: 'https://50projects50days.com/img/projects-img/8-form-wave.png',link: 'FormWave',},
router/index.js
中添加路由選項:
{path: '/FormWave',name: 'FormWave',component: () => import('@/projects/FormWave.vue'),},
路由守衛可后續擴展身份驗證邏輯,跳轉到注冊或首頁。
🧠 小結
完成了通用場景下的表單樣式界面,可以為你以后的表單設計以及登錄頁面提供一些靈感進行參考!!!🚀
👉 下一篇,我們將完成聲音組件 Sound Board
組件,可以實現點擊發出對應的聲音!🚀