Vue3+node.js实现注册

发布于:2024-11-29 ⋅ 阅读:(8) ⋅ 点赞:(0)

效果图
在这里插入图片描述

前端代码实现

<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)
    }
})