Files
art-design/src/views/auth/register/index.vue
2026-01-10 21:41:23 +08:00

209 lines
4.9 KiB
Vue

<!-- 注册页面 -->
<template>
<div class="flex w-full h-screen">
<LoginLeftView />
<div class="relative flex-1">
<AuthTopBar />
<div class="auth-right-wrap">
<div class="form">
<h3 class="title">{{ $t('register.title') }}</h3>
<p class="sub-title">{{ $t('register.subTitle') }}</p>
<ElForm class="mt-7.5" ref="formRef" :model="formData" :rules="rules" label-position="top"
:key="formKey">
<ElFormItem prop="username">
<ElInput class="custom-height" v-model.trim="formData.username"
:placeholder="$t('register.placeholder.username')" />
</ElFormItem>
<ElFormItem prop="password">
<ElInput class="custom-height" v-model.trim="formData.password"
:placeholder="$t('register.placeholder.password')" type="password" autocomplete="off"
show-password />
</ElFormItem>
<ElFormItem prop="confirmPassword">
<ElInput class="custom-height" v-model.trim="formData.confirmPassword"
:placeholder="$t('register.placeholder.confirmPassword')" type="password"
autocomplete="off" @keyup.enter="register" show-password />
</ElFormItem>
<ElFormItem prop="agreement">
<ElCheckbox v-model="formData.agreement">
{{ $t('register.agreeText') }}
<RouterLink style="color: var(--theme-color); text-decoration: none"
to="/privacy-policy">{{ $t('register.privacyPolicy') }}</RouterLink>
</ElCheckbox>
</ElFormItem>
<div style="margin-top: 15px">
<ElButton class="w-full custom-height" type="primary" @click="register" :loading="loading"
v-ripple>
{{ $t('register.submitBtnText') }}
</ElButton>
</div>
<div class="mt-5 text-sm text-g-600">
<span>{{ $t('register.hasAccount') }}</span>
<RouterLink class="text-theme" :to="{ name: 'Login' }">{{
$t('register.toLogin')
}}</RouterLink>
</div>
</ElForm>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { useI18n } from 'vue-i18n'
defineOptions({ name: 'Register' })
const USERNAME_MIN_LENGTH = 3
const USERNAME_MAX_LENGTH = 20
const PASSWORD_MIN_LENGTH = 6
const REDIRECT_DELAY = 1000
const { t, locale } = useI18n()
const router = useRouter()
const formRef = ref()
const loading = ref(false)
const formKey = ref(0)
// 监听语言切换,重置表单
watch(locale, () => {
formKey.value++
})
const formData = reactive({
username: '',
password: '',
confirmPassword: '',
agreement: false
})
/**
* 验证密码
* 当密码输入后,如果确认密码已填写,则触发确认密码的验证
*/
const validatePassword = (_rule, value, callback) => {
if (!value) {
callback(new Error(t('register.placeholder.password')))
return
}
if (formData.confirmPassword) {
formRef.value?.validateField('confirmPassword')
}
callback()
}
/**
* 验证确认密码
* 检查确认密码是否与密码一致
*/
const validateConfirmPassword = (
_rule,
value,
callback
) => {
if (!value) {
callback(new Error(t('register.rule.confirmPasswordRequired')))
return
}
if (value !== formData.password) {
callback(new Error(t('register.rule.passwordMismatch')))
return
}
callback()
}
/**
* 验证用户协议
* 确保用户已勾选同意协议
*/
const validateAgreement = (_rule, value, callback) => {
if (!value) {
callback(new Error(t('register.rule.agreementRequired')))
return
}
callback()
}
const rules = computed(() => ({
username: [
{ required: true, message: t('register.placeholder.username'), trigger: 'blur' },
{
min: USERNAME_MIN_LENGTH,
max: USERNAME_MAX_LENGTH,
message: t('register.rule.usernameLength'),
trigger: 'blur'
}
],
password: [
{ required: true, validator: validatePassword, trigger: 'blur' },
{
min: PASSWORD_MIN_LENGTH,
message: t('register.rule.passwordLength'),
trigger: 'blur'
}
],
confirmPassword: [{ required: true, validator: validateConfirmPassword, trigger: 'blur' }],
agreement: [{ validator: validateAgreement, trigger: 'change' }]
}))
/**
* 注册用户
* 验证表单后提交注册请求
*/
const register = async () => {
if (!formRef.value) return
try {
await formRef.value.validate()
loading.value = true
// TODO: 替换为真实 API 调用
// const params = {
// username: formData.username,
// password: formData.password
// }
// const res = await AuthService.register(params)
// if (res.code === ApiStatus.success) {
// ElMessage.success('注册成功')
// toLogin()
// }
// 模拟注册请求
setTimeout(() => {
loading.value = false
ElMessage.success('注册成功')
toLogin()
}, REDIRECT_DELAY)
} catch (error) {
console.error('表单验证失败:', error)
loading.value = false
}
}
/**
* 跳转到登录页面
*/
const toLogin = () => {
setTimeout(() => {
router.push({ name: 'Login' })
}, REDIRECT_DELAY)
}
</script>
<style scoped>
@import '../login/style.css';
</style>