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.
113 lines
3.0 KiB
113 lines
3.0 KiB
<script setup lang="ts">
|
|
import type { FormError, FormSubmitEvent } from '@nuxt/ui'
|
|
|
|
definePageMeta({
|
|
title: '登录',
|
|
layout: 'not-login',
|
|
})
|
|
|
|
type LoginFormState = {
|
|
email: string
|
|
password: string
|
|
}
|
|
|
|
const state = reactive<LoginFormState>({
|
|
email: '',
|
|
password: '',
|
|
})
|
|
|
|
const loading = ref(false)
|
|
const resultType = ref<'success' | 'error' | ''>('')
|
|
const resultMessage = ref('')
|
|
|
|
const validate = (formState: LoginFormState): FormError[] => {
|
|
const errors: FormError[] = []
|
|
|
|
if (!formState.email) {
|
|
errors.push({ name: 'email', message: '请输入邮箱' })
|
|
} else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(formState.email)) {
|
|
errors.push({ name: 'email', message: '邮箱格式不正确' })
|
|
}
|
|
|
|
if (!formState.password) {
|
|
errors.push({ name: 'password', message: '请输入密码' })
|
|
} else if (formState.password.length < 6) {
|
|
errors.push({ name: 'password', message: '密码至少 6 位' })
|
|
}
|
|
|
|
return errors
|
|
}
|
|
|
|
const onSubmit = async (_event: FormSubmitEvent<LoginFormState>) => {
|
|
resultType.value = ''
|
|
resultMessage.value = ''
|
|
loading.value = true
|
|
|
|
try {
|
|
await new Promise((resolve) => setTimeout(resolve, 800))
|
|
resultType.value = 'success'
|
|
resultMessage.value = `登录成功,欢迎 ${state.email}`
|
|
} catch {
|
|
resultType.value = 'error'
|
|
resultMessage.value = '登录失败,请稍后重试'
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<div class="max-w-md mx-auto py-10">
|
|
<UCard>
|
|
<template #header>
|
|
<div class="space-y-1">
|
|
<h1 class="text-xl font-semibold">欢迎登录</h1>
|
|
<p class="text-sm text-muted">请输入邮箱和密码继续</p>
|
|
</div>
|
|
</template>
|
|
|
|
<UForm :state="state" :validate="validate" class="space-y-4" @submit="onSubmit">
|
|
<UFormField label="邮箱" name="email" required>
|
|
<UInput
|
|
v-model="state.email"
|
|
type="email"
|
|
placeholder="you@example.com"
|
|
autocomplete="email"
|
|
class="w-full"
|
|
/>
|
|
</UFormField>
|
|
|
|
<UFormField label="密码" name="password" required>
|
|
<UInput
|
|
v-model="state.password"
|
|
type="password"
|
|
placeholder="请输入密码"
|
|
autocomplete="current-password"
|
|
class="w-full"
|
|
/>
|
|
</UFormField>
|
|
|
|
<UButton type="submit" block :loading="loading">
|
|
立即登录
|
|
</UButton>
|
|
</UForm>
|
|
|
|
<UAlert
|
|
v-if="resultType"
|
|
:color="resultType === 'success' ? 'success' : 'error'"
|
|
:title="resultType === 'success' ? '操作成功' : '操作失败'"
|
|
:description="resultMessage"
|
|
class="mt-4"
|
|
/>
|
|
|
|
<div class="mt-4 flex items-center justify-between text-sm">
|
|
<NuxtLink to="/register" class="text-primary hover:underline">
|
|
去注册
|
|
</NuxtLink>
|
|
<NuxtLink to="/forgot-password" class="text-muted hover:underline">
|
|
忘记密码?
|
|
</NuxtLink>
|
|
</div>
|
|
</UCard>
|
|
</div>
|
|
</template>
|