You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
6.5 KiB
6.5 KiB
Login/Register Toast 体验优化
Goal: 用 vue3-toastify 替换登录/注册页面的静态错误提示,提升用户体验。
Architecture: 在 login.vue 和 register.vue 中注入 toast 服务,移除静态 form-error div,改为 toast 弹出提示。成功/加载状态同样使用 toast 反馈。
Tech Stack: vue3-toastify (已安装), Nuxt 3, Vue 3 Composition API
文件变更
- Modify:
app/pages/auth/login.vue - Modify:
app/pages/auth/register.vue
Task 1: 优化 login.vue
Files:
-
Modify:
app/pages/auth/login.vue -
Step 1: 注入 toast 服务
在 <script setup> 开头添加:
const { $toast } = useNuxtApp()
- Step 2: 移除 form-error div 并添加 toast 注入
删除模板中的:
<div v-if="loginError" class="form-error">{{ loginError }}</div>
- Step 3: 修改 handleLogin 错误处理
将:
loginError.value = e?.data?.statusMessage || e?.message || '登录失败'
改为:
$toast.error(e?.data?.statusMessage || e?.message || '登录失败')
await fetchCaptcha()
- Step 4: 修改 handleLogin 成功处理
将:
await refresh(true)
await navigateTo(redirect.value)
改为:
$toast.success('登录成功!')
await refresh(true)
await navigateTo(redirect.value)
- Step 5: 修改 fetchCaptcha 加载状态
将:
async function fetchCaptcha() {
captcha.loading = true
try {
const res = await $fetch<{ code: number; data: { captchaId: string; imageSvg: string } }>('/api/auth/captcha')
captcha.id = res.data.captchaId
captcha.svg = res.data.imageSvg
captcha.answer = ''
} catch (e: any) {
console.error('获取验证码失败', e)
} finally {
captcha.loading = false
}
}
改为:
async function fetchCaptcha() {
captcha.loading = true
const loadingToast = $toast.loading('加载验证码...', { toastId: 'captcha-loading' })
try {
const res = await $fetch<{ code: number; data: { captchaId: string; imageSvg: string } }>('/api/auth/captcha')
captcha.id = res.data.captchaId
captcha.svg = res.data.imageSvg
captcha.answer = ''
$toast.update(loadingToast, { render: '验证码加载成功', type: 'success', isLoading: false, autoClose: 1500 })
} catch (e: any) {
console.error('获取验证码失败', e)
$toast.update(loadingToast, { render: '验证码加载失败', type: 'error', isLoading: false, autoClose: 3000 })
} finally {
captcha.loading = false
}
}
- Step 6: 删除 form-error 相关样式
删除 CSS 中的 .form-error { ... } 样式块
- Step 7: 提交代码
git add app/pages/auth/login.vue
git commit -m "feat(auth): add toast notifications to login page"
Task 2: 优化 register.vue
Files:
-
Modify:
app/pages/auth/register.vue -
Step 1: 注入 toast 服务
在 <script setup> 开头添加:
const { $toast } = useNuxtApp()
- Step 2: 移除 form-error div
删除模板中的:
<div v-if="registerError" class="form-error">{{ registerError }}</div>
- Step 3: 移除 registerError ref
删除:
const registerError = ref('')
- Step 4: 修改 handleRegister 表单验证错误
将:
if (registerForm.password !== registerForm.confirmPassword) {
registerError.value = '两次密码输入不一致'
return
}
改为:
if (registerForm.password !== registerForm.confirmPassword) {
$toast.error('两次密码输入不一致')
return
}
- Step 5: 修改 handleRegister 请求错误处理
将:
} catch (e: any) {
registerError.value = e?.data?.statusMessage || e?.message || '注册失败'
await fetchCaptcha()
改为:
} catch (e: any) {
$toast.error(e?.data?.statusMessage || e?.message || '注册失败')
await fetchCaptcha()
- Step 6: 修改 handleRegister 成功处理
将:
await navigateTo('/auth/login?tab=login')
改为:
$toast.success('注册成功!正在跳转...')
setTimeout(() => navigateTo('/auth/login?tab=login'), 1500)
- Step 7: 修改 fetchCaptcha 加载状态 (同 login.vue)
将:
async function fetchCaptcha() {
captcha.loading = true
try {
const res = await $fetch<{ code: number; data: { captchaId: string; imageSvg: string } }>('/api/auth/captcha')
captcha.id = res.data.captchaId
captcha.svg = res.data.imageSvg
captcha.answer = ''
} catch (e: any) {
console.error('获取验证码失败', e)
} finally {
captcha.loading = false
}
}
改为:
async function fetchCaptcha() {
captcha.loading = true
const loadingToast = $toast.loading('加载验证码...', { toastId: 'captcha-loading' })
try {
const res = await $fetch<{ code: number; data: { captchaId: string; imageSvg: string } }>('/api/auth/captcha')
captcha.id = res.data.captchaId
captcha.svg = res.data.imageSvg
captcha.answer = ''
$toast.update(loadingToast, { render: '验证码加载成功', type: 'success', isLoading: false, autoClose: 1500 })
} catch (e: any) {
console.error('获取验证码失败', e)
$toast.update(loadingToast, { render: '验证码加载失败', type: 'error', isLoading: false, autoClose: 3000 })
} finally {
captcha.loading = false
}
}
- Step 8: 删除 form-error 和 registerError 相关样式/逻辑
删除 CSS 中的 .form-error { ... } 样式块
- Step 9: 提交代码
git add app/pages/auth/register.vue
git commit -m "feat(auth): add toast notifications to register page"
验证步骤
- 启动开发服务器:
npm run dev - 访问
/auth/login,测试以下场景:- 输入错误信息点击登录 → 应看到 toast 错误提示
- 登录成功 → 应看到 toast 成功提示并跳转
- 刷新页面 → 验证码加载中应有 toast 提示
- 访问
/auth/register,测试以下场景:- 两次密码不一致 → 应看到 toast 错误提示
- 注册成功 → 应看到 toast 成功提示并延迟跳转
- 验证码加载 → 应看到 toast 加载状态
Plan complete. 可选执行方式:
1. Subagent-Driven (推荐) - 我派发独立 subagent 执行每个任务 2. Inline Execution - 本会话内顺序执行
选择哪种方式?