效果图
前端代码实现
<template>
<div class="register-container">
<el-card class="register-card">
<template #header>
<div class="card-header">
<span>注册</span>
</div>
</template>
<el-form label-width="80px" ref="formRef" :model="formData" :rules="rules">
<el-form-item label="用户名" prop="username">
<el-input v-model="formData.username" placeholder="请输入用户名"></el-input>
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input v-model="formData.password" type="password" placeholder="请输入密码"></el-input>
</el-form-item>
<el-form-item label="确认密码" prop="confirmPassword">
<el-input v-model="formData.confirmPassword" type="password" placeholder="请确认密码"></el-input>
</el-form-item>
<el-form-item label="姓名" prop="name">
<el-input v-model="formData.name" placeholder="请输入姓名"></el-input>
</el-form-item>
<el-form-item label="性别" prop="sex">
<el-select v-model="formData.sex" placeholder="请选择性别">
<el-option label="男" value="男"></el-option>
<el-option label="女" value="女"></el-option>
</el-select>
</el-form-item>
<el-form-item label="邮箱" prop="email">
<el-input v-model="formData.email" placeholder="请输入邮箱"></el-input>
</el-form-item>
<el-form-item>
<el-button style="width: 100%;" @click="handleSubmit" type="primary">注册</el-button>
</el-form-item>
<el-form-item>
<el-button link type="info" @click="toggleToLogin">已有账号?去登录</el-button>
</el-form-item>
</el-form>
</el-card>
</div>
</template>
<script setup>
import { ElMessage } from 'element-plus';
import axios from 'axios';
import { reactive, ref } from 'vue';
// 初始化
const formRef = ref(null);
// 注册跳转
const toggleToLogin = () => {
location.href = '/login';
}
// 表单数据
const formData = ref({
username: '',
password: '',
confirmPassword: '',
name: '',
sex: '',
email: ''
});
const validateConfirmPassword = (rule, value, callback) => {
if (value !== formData.value.password) {
callback(new Error('两次输入的密码不一致'));
} else {
callback();
}
};
// 校验规则
const rules = reactive({
username: [
{ required: true, message: '请输入用户名', trigger: 'blur' },
{ min: 3, max: 20, message: '长度在3到20个字符', trigger: 'blur' }
],
password: [
{ required: true, message: '请输入密码', trigger: 'blur' },
{ min: 6, max: 20, message: '长度在6到20个字符', trigger: 'blur' }
],
confirmPassword: [
{ required: true, message: '请确认密码', trigger: 'blur' },
{ validator: validateConfirmPassword, trigger: 'blur' } // 自定义验证
],
name: [
{ required: true, message: '请输入姓名', trigger: 'blur' }
],
sex: [
{ required: true, message: '请选择性别', trigger: 'change' }
],
email: [
{ required: true, message: '请输入邮箱', trigger: 'blur' },
{ type: 'email', message: '邮箱格式不正确', trigger: 'blur' }
]
});
// 注册处理
const handleSubmit = async () => {
const form = formRef.value;
if (!form) return;
try {
await form.validate();
const res = await axios.post('http://localhost:3030/user/register', formData.value);
if (res.data.code === 200) {
ElMessage.success(res.data.message || '注册成功');
location.href = '/login';
} else {
ElMessage.error(res.data.message || '注册失败');
}
} catch (error) {
console.error('注册请求错误', error);
ElMessage.error(error.response?.data?.message || '注册失败,请稍后重试');
}
}
</script>
<style scoped>
.register-container {
min-height: 100vh;
display: flex;
background-color: aqua;
align-items: center;
justify-content: center;
}
.register-card {
width: 400px;
border-radius: 8px;
}
.card-header {
font-size: 24px;
font-weight: bold;
text-align: center;
}
</style>
后端代码实现
//注册
router.post('/register',async (req,res)=>{
try {
const {name,username,password,sex,email} = req.body
//必填字段
if(!name || !username || !password || !sex ||!email){
return res.json({
code:400,
message:'请填写所有必填字段'
})
}
//检查用户是否存在
const checkSql = 'select count(*) as count from user where username = ?'
const [[{count}]] = await pool.query(checkSql,[username])
if(count > 0){
return res.json({
code:400,
message:'用户已存在'
})
}
//插入新用户
const insertSql = 'insert into user (username,password,name,sex,email) values (?,?,?,?,?)'
const [result] =await pool.query(insertSql,[username,password,name,sex,email])
success(res,null,'注册成功')
} catch (error) {
handleError(res,error)
}
})