201 lines
No EOL
5.3 KiB
Vue
201 lines
No EOL
5.3 KiB
Vue
<template>
|
||
<div class="register-container">
|
||
<el-card class="register-card">
|
||
<template #header>
|
||
<div class="register-header">
|
||
<img src="../assets/logo.png" alt="logo" class="register-logo">
|
||
<h2>用户注册</h2>
|
||
</div>
|
||
</template>
|
||
|
||
<el-form
|
||
ref="registerFormRef"
|
||
:model="registerForm"
|
||
:rules="registerRules"
|
||
label-width="100px"
|
||
@keyup.enter="handleRegister">
|
||
|
||
<el-form-item label="用户名" prop="username">
|
||
<el-input
|
||
v-model="registerForm.username"
|
||
placeholder="请输入用户名"
|
||
:prefix-icon="User"
|
||
clearable />
|
||
</el-form-item>
|
||
|
||
<el-form-item label="昵称" prop="nickname">
|
||
<el-input
|
||
v-model="registerForm.nickname"
|
||
placeholder="请输入昵称"
|
||
:prefix-icon="UserFilled"
|
||
clearable />
|
||
</el-form-item>
|
||
|
||
<el-form-item label="密码" prop="password">
|
||
<el-input
|
||
v-model="registerForm.password"
|
||
type="password"
|
||
placeholder="请输入密码"
|
||
:prefix-icon="Lock"
|
||
show-password />
|
||
</el-form-item>
|
||
|
||
<el-form-item label="确认密码" prop="confirmPassword">
|
||
<el-input
|
||
v-model="registerForm.confirmPassword"
|
||
type="password"
|
||
placeholder="请再次输入密码"
|
||
:prefix-icon="Lock"
|
||
show-password />
|
||
</el-form-item>
|
||
|
||
<el-button
|
||
type="primary"
|
||
class="register-button"
|
||
:loading="loading"
|
||
@click="handleRegister">
|
||
注册
|
||
</el-button>
|
||
<div class="login-link">
|
||
已有账号?
|
||
<el-button
|
||
type="primary"
|
||
link
|
||
@click="router.push('/login')">
|
||
立即登录
|
||
</el-button>
|
||
</div>
|
||
</el-form>
|
||
</el-card>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { ref } from 'vue'
|
||
import { useRouter } from 'vue-router'
|
||
import { ElMessage } from 'element-plus'
|
||
import { User, UserFilled, Lock } from '@element-plus/icons-vue'
|
||
import { UserAPI } from '../api/user'
|
||
|
||
const router = useRouter()
|
||
const registerFormRef = ref(null)
|
||
const loading = ref(false)
|
||
|
||
const registerForm = ref({
|
||
username: '',
|
||
nickname: '',
|
||
password: '',
|
||
confirmPassword: ''
|
||
})
|
||
|
||
const validatePass = (rule, value, callback) => {
|
||
if (value === '') {
|
||
callback(new Error('请输入密码'))
|
||
} else {
|
||
if (registerForm.value.confirmPassword !== '') {
|
||
registerFormRef.value.validateField('confirmPassword')
|
||
}
|
||
callback()
|
||
}
|
||
}
|
||
|
||
const validatePass2 = (rule, value, callback) => {
|
||
if (value === '') {
|
||
callback(new Error('请再次输入密码'))
|
||
} else if (value !== registerForm.value.password) {
|
||
callback(new Error('两次输入密码不一致!'))
|
||
} else {
|
||
callback()
|
||
}
|
||
}
|
||
|
||
const registerRules = {
|
||
username: [
|
||
{ required: true, message: '请输入用户名', trigger: 'blur' },
|
||
{ min: 3, max: 20, message: '长度在 3 到 20 个字符', trigger: 'blur' }
|
||
],
|
||
nickname: [
|
||
{ required: true, message: '请输入昵称', trigger: 'blur' },
|
||
{ min: 2, max: 20, message: '长度在 2 到 20 个字符', trigger: 'blur' }
|
||
],
|
||
password: [
|
||
{ validator: validatePass, trigger: 'blur' },
|
||
{ min: 6, message: '密码长度不能小于6位', trigger: 'blur' }
|
||
],
|
||
confirmPassword: [
|
||
{ validator: validatePass2, trigger: 'blur' }
|
||
]
|
||
}
|
||
|
||
const handleRegister = async () => {
|
||
if (!registerFormRef.value) return
|
||
|
||
await registerFormRef.value.validate(async (valid) => {
|
||
if (valid) {
|
||
loading.value = true
|
||
try {
|
||
const response = await UserAPI.register({
|
||
username: registerForm.value.username,
|
||
nickname: registerForm.value.nickname,
|
||
password: registerForm.value.password
|
||
})
|
||
|
||
if (response.retcode === 0) {
|
||
ElMessage.success('注册成功,请登录')
|
||
router.push('/login')
|
||
}
|
||
} catch (error) {
|
||
console.error('注册失败:', error)
|
||
} finally {
|
||
loading.value = false
|
||
}
|
||
}
|
||
})
|
||
}
|
||
</script>
|
||
|
||
<style scoped>
|
||
.register-container {
|
||
height: 100vh;
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
background-color: #f0f2f5;
|
||
background-image: url('data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1440 320"%3E%3Cpath fill="%230099ff" fill-opacity="0.1" d="M0,160L48,144C96,128,192,96,288,106.7C384,117,480,171,576,165.3C672,160,768,96,864,90.7C960,85,1056,139,1152,144C1248,149,1344,107,1392,85.3L1440,64L1440,320L1392,320C1344,320,1248,320,1152,320C1056,320,960,320,864,320C768,320,672,320,576,320C480,320,384,320,288,320C192,320,96,320,48,320L0,320Z"%3E%3C/path%3E%3C/svg%3E');
|
||
background-repeat: no-repeat;
|
||
background-position: bottom;
|
||
background-size: cover;
|
||
}
|
||
|
||
.register-card {
|
||
width: 480px;
|
||
margin: 20px;
|
||
border-radius: 8px;
|
||
box-shadow: 0 2px 12px 0 rgba(0,0,0,0.1);
|
||
}
|
||
|
||
.register-header {
|
||
text-align: center;
|
||
margin-bottom: 20px;
|
||
}
|
||
|
||
.register-logo {
|
||
width: 64px;
|
||
height: 64px;
|
||
margin-bottom: 16px;
|
||
}
|
||
|
||
.register-button {
|
||
width: 100%;
|
||
}
|
||
|
||
.login-link {
|
||
text-align: center;
|
||
margin-top: 12px;
|
||
color: #606266;
|
||
}
|
||
|
||
:deep(.el-form-item__label) {
|
||
font-weight: 500;
|
||
}
|
||
</style> |