blob: 67a262fd988b03807c66c5040e0988c0647d6b8c [file] [log] [blame]
<template>
<div class="register-page">
<div class="bg-decoration">
<div class="shape shape-1"></div>
<div class="shape shape-2"></div>
<div class="shape shape-3"></div>
</div>
<div class="register-container">
<div class="register-card">
<div class="register-header">
<div class="logo">
<el-icon size="48" color="#a8edea"><UserFilled /></el-icon>
</div>
<h1 class="title">加入 PT Tracker</h1>
<p class="subtitle">开始你的资源分享之旅</p>
</div>
<!-- 注册表单 -->
<el-form
ref="registerFormRef"
:model="registerForm"
:rules="registerRules"
class="register-form"
size="large"
>
<el-form-item prop="username">
<el-input
v-model="registerForm.username"
placeholder="请输入用户名"
clearable
:prefix-icon="User"
/>
</el-form-item>
<el-form-item prop="email">
<el-input
v-model="registerForm.email"
placeholder="请输入邮箱地址"
clearable
:prefix-icon="Message"
/>
</el-form-item>
<el-form-item prop="password">
<el-input
v-model="registerForm.password"
type="password"
placeholder="请输入密码"
show-password
:prefix-icon="Lock"
/>
</el-form-item>
<el-form-item prop="confirmPassword">
<el-input
v-model="registerForm.confirmPassword"
type="password"
placeholder="请确认密码"
show-password
:prefix-icon="Lock"
/>
</el-form-item>
<el-form-item prop="agreement">
<el-checkbox v-model="registerForm.agreement">
我已阅读并同意
<el-link type="primary" :underline="false">《用户协议》</el-link>
<el-link type="primary" :underline="false">《隐私政策》</el-link>
</el-checkbox>
</el-form-item>
<el-form-item>
<el-button
type="primary"
:loading="registerLoading"
style="width: 100%"
@click="handleRegister"
>
<span v-if="!registerLoading">注册</span>
<span v-else>注册中...</span>
</el-button>
</el-form-item>
</el-form>
<div class="register-footer">
<span class="footer-text">已有账号?</span>
<el-link
type="primary"
:underline="false"
@click="$router.push('/login')"
>
立即登录
</el-link>
</div>
</div>
</div>
</div>
</template>
<script>
import { ref, reactive, computed } from 'vue'
import { useRouter } from 'vue-router'
import { useStore } from 'vuex'
import { User, Lock, Message, UserFilled } from '@element-plus/icons-vue'
export default {
name: 'RegisterView',
components: {
UserFilled
},
setup() {
const router = useRouter()
const store = useStore()
const registerFormRef = ref()
// 从store获取登录加载状态(注册和登录共用同一个loading状态)
const registerLoading = computed(() => store.getters['auth/loginLoading'])
// 表单数据
const registerForm = reactive({
username: '',
email: '',
password: '',
confirmPassword: '',
agreement: false
})
// 自定义验证规则
const validateConfirmPassword = (rule, value, callback) => {
if (value === '') {
callback(new Error('请再次输入密码'))
} else if (value !== registerForm.password) {
callback(new Error('两次输入密码不一致'))
} else {
callback()
}
}
const validateAgreement = (rule, value, callback) => {
if (!value) {
callback(new Error('请先同意用户协议和隐私政策'))
} else {
callback()
}
}
// 验证规则
const registerRules = {
username: [
{ required: true, message: '请输入用户名', trigger: 'blur' },
{ min: 3, max: 20, message: '用户名长度在3到20个字符', trigger: 'blur' },
{ pattern: /^[a-zA-Z0-9_]+$/, message: '用户名只能包含字母、数字和下划线', trigger: 'blur' }
],
email: [
{ required: true, message: '请输入邮箱地址', trigger: 'blur' },
{ type: 'email', message: '请输入正确的邮箱格式', trigger: 'blur' }
],
password: [
{ required: true, message: '请输入密码', trigger: 'blur' },
{ min: 6, max: 20, message: '密码长度在6到20个字符', trigger: 'blur' }
],
confirmPassword: [
{ required: true, validator: validateConfirmPassword, trigger: 'blur' }
],
agreement: [
{ required: true, validator: validateAgreement, trigger: 'change' }
]
}
// 注册处理
const handleRegister = async () => {
try {
// 表单验证
const valid = await registerFormRef.value.validate()
if (!valid) return
// 调用store的注册action
await store.dispatch('auth/register', {
username: registerForm.username,
email: registerForm.email,
password: registerForm.password
})
// 注册成功,跳转到首页
router.push('/home')
} catch (error) {
console.error('注册失败:', error)
// 错误信息已经在store中通过ElMessage显示了
}
}
return {
registerFormRef,
registerForm,
registerRules,
registerLoading,
handleRegister,
User,
Lock,
Message
}
}
}
</script>