Cùng tiếp tục với Bài 9 – Tạo Form và Validate trong NuxtJS. Đây là phần thiết yếu để bạn xây dựng chức năng đăng nhập, đăng ký, gửi dữ liệu, tương tác với API backend.
1. Tạo form đơn giản
Ví dụ tạo form đăng nhập trong pages/login.vue
:
<script setup>
import { ref } from 'vue'
const email = ref('')
const password = ref('')
</script>
<template>
<form @submit.prevent="console.log(email, password)">
<input v-model="email" type="email" placeholder="Email" />
<input v-model="password" type="password" placeholder="Mật khẩu" />
<button type="submit">Đăng nhập</button>
</form>
</template>
v-model
: binding 2 chiều giữa input và biến@submit.prevent
: ngăn reload trang
2. Validate thủ công (basic)
<script setup>
const email = ref('')
const password = ref('')
const error = ref('')
function handleSubmit() {
if (!email.value || !password.value) {
error.value = 'Vui lòng điền đầy đủ thông tin'
return
}
error.value = ''
console.log('Đăng nhập với:', email.value, password.value)
}
</script>
<template>
<form @submit.prevent="handleSubmit">
<input v-model="email" type="email" placeholder="Email" />
<input v-model="password" type="password" placeholder="Mật khẩu" />
<div style="color:red">{{ error }}</div>
<button type="submit">Gửi</button>
</form>
</template>
3. Validate nâng cao với yup
+ @vuelidate/core
(optional)
Cài thêm nếu bạn muốn:
npm install @vuelidate/core @vuelidate/validators
Rồi cấu hình như sau (sẽ giới thiệu sau ở bài mở rộng nếu bạn cần).
4. Submit form và gọi API
<script setup>
const email = ref('')
const password = ref('')
const message = ref('')
const loading = ref(false)
async function login() {
loading.value = true
try {
const res = await $fetch('https://reqres.in/api/login', {
method: 'POST',
body: { email: email.value, password: password.value }
})
message.value = 'Đăng nhập thành công!'
console.log('Token:', res.token)
} catch (err) {
message.value = 'Sai tài khoản hoặc lỗi kết nối'
} finally {
loading.value = false
}
}
</script>
<template>
<form @submit.prevent="login">
<input v-model="email" placeholder="Email" />
<input v-model="password" type="password" placeholder="Mật khẩu" />
<button :disabled="loading">Đăng nhập</button>
<p>{{ message }}</p>
</form>
</template>
5. UX nâng cao
- Loading state
- Thông báo lỗi
- Trạng thái submit thành công
6. Dùng useFormState()
tùy chỉnh (optional)
Tự viết composable để quản lý form:
export const useFormState = () => {
return reactive({
email: '',
password: '',
loading: false,
error: '',
success: ''
})
}
Bạn đã học được
- Tạo form bằng
v-model
- Xử lý submit, validate cơ bản
- Gọi API với
$fetch()
sau khi submit - Hiển thị thông báo, loading, error
- Tư duy chuẩn để scale form lớn
Bài tập mở rộng
- Tạo page
/register
có form đăng ký - Validate: email không rỗng, password >= 6 ký tự
- Gọi API
https://reqres.in/api/register
để thử nghiệm
Thảo luận