vue-注册登录

举报
林太白 发表于 2025/01/27 18:37:13 2025/01/27
【摘要】 vue-注册登录的实现

注册登录

注册

(1)注册流程

  1. 用户点击注册按钮,触发注册事件
  2. 调用注册接口,将用户名和密码传递给后端
  3. 后端验证用户名是否已存在,如果已存在则返回错误信息,否则将用户名和密码保存到数据库中
  4. 前端接收到注册成功的响应后,跳转到登录页面

(2)注册接口

  1. 注册接口需要接收用户名和密码作为参数

(3)注册页面

☞ 在src下面的pages里面新建一个register.vue页面

注册页面需要有用户名和密码的输入框和登录按钮

<template>
<div class="pageregister backbaige">
<el-form ref="registerRef" :model="registerForm" :rules="registerRules" class="register-form">
<h3 class="title">后台管理系统</h3>
<el-form-item prop="username">
<el-input v-model="registerForm.username" type="text" size="large" auto-complete="off" placeholder="账号">
    <template #prefix>
        <svg-icon icon-class="user" class="el-input__icon input-icon" /></template>
</el-input>
</el-form-item>
<el-form-item prop="password">
<el-input v-model="registerForm.password" type="password" size="large" auto-complete="off" placeholder="密码" @keyup.enter="handleRegister">
    <template #prefix>
        <svg-icon icon-class="password" class="el-input__icon input-icon" /></template>
</el-input>
</el-form-item>
<el-form-item prop="confirmPassword">
<el-input v-model="registerForm.confirmPassword" type="password" size="large" auto-complete="off" placeholder="确认密码" @keyup.enter="handleRegister">
    <template #prefix>
        <svg-icon icon-class="password" class="el-input__icon input-icon" /></template>
</el-input>
</el-form-item>

<el-form-item prop="code" v-if="showVerificationCode">
<el-input size="large" v-model="registerForm.code" auto-complete="off" placeholder="验证码" style="width: 50%;margin-right: 2%;" @keyup.enter="handleRegister">
    <template #prefix>
        <svg-icon icon-class="validCode" class="el-input__icon input-icon" /></template>
</el-input>
<div class="register-code" style="width:48%">
    <VerificationCode  style="width: 100%;height: 40px;" :length="4"></VerificationCode>
</div>
</el-form-item>
<el-form-item style="width:100%;">
<el-button :loading="loading" size="large" type="primary" style="width:100%;" @click.prevent="handleRegister">
    <span v-if="!loading">注 册</span>
    <span v-else>注 册 中...</span>
</el-button>
<div style="float: right;">
    <router-link class="link-type" :to="'/login'">使用已有账户登录</router-link>
</div>
</el-form-item>
</el-form>
</div>
</template>
<script setup>
import { ref } from "vue";
import { useRouter } from 'vue-router'
import { getCodeImg, register } from "@/api/login";
import config from '@/utils/config.js';
const showVerificationCode=ref(true);  //自定义验证码开关
const router = useRouter();
const registerForm = ref({
    username: "admin",
    password: "admin123",
    confirmPassword: "admin123",
    code: "",
    uuid: ""
});
const registerRef=ref(null);

const equalToPassword = (rule, value, callback) => {
    if (registerForm.value.password !== value) {
        callback(new Error("两次输入的密码不一致"));
    } else {
        callback();
    }
};
const registerRules = {
    username: [
        { required: true, trigger: "blur", message: "请输入您的账号" },
        { min: 2, max: 20, message: "用户账号长度必须介于 2 和 20 之间", trigger: "blur" }
    ],
    password: [
        { required: true, trigger: "blur", message: "请输入您的密码" },
        { min: 5, max: 20, message: "用户密码长度必须介于 5 和 20 之间", trigger: "blur" },
        { pattern: /^[^<>"'|\\]+$/, message: "不能包含非法字符:<> \" ' \\\ |", trigger: "blur" }
    ],
    confirmPassword: [
        { required: true, trigger: "blur", message: "请再次输入您的密码" },
        { required: true, validator: equalToPassword, trigger: "blur" }
    ],
    code: [{ required: true, trigger: "change", message: "请输入验证码" }]
};

const codeUrl = ref("");
const loading = ref(false);

const captchaEnabled = ref(false); //验证码开关

const handleRegister = async () => {
  await registerRef.value.validate((valid, fields) => {
    if (valid) {
      console.log('submit!');
      register(registerForm.value).then(res => {
        if(res.code==200){
              router.push("/login");
        }else{}
      }).catch(() => {});
    } else {
      console.log('error submit!', fields)
    }
  })
}
</script>
<style lang='scss' scoped>
.pageregister {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100%;
}

.title {
    margin: 0px auto 30px auto;
    text-align: center;
    color: #707070;
}

.register-form {
    border-radius: 8px;
    width: 400px;
    padding: 25px 25px 5px 25px;

    .el-input {
        height: 40px;

        input {
            height: 40px;
        }
    }

    .input-icon {
        height: 39px;
        width: 14px;
        margin-left: 0px;
    }
}

.register-tip {
    font-size: 13px;
    text-align: center;
    color: #bfbfbf;
}

.register-code {
    width: 33%;
    height: 40px;
    float: right;

    img {
        cursor: pointer;
        vertical-align: middle;
    }
}

.el-register-footer {
    height: 40px;
    line-height: 40px;
    position: fixed;
    bottom: 0;
    width: 100%;
    text-align: center;
    color: #fff;
    font-family: Arial;
    font-size: 12px;
    letter-spacing: 1px;
}
.register-code-img {
    height: 40px;
    padding-left: 12px;
}
</style>

最后效果如下

登录

(1)登录流程

  1. 用户点击登录按钮,触发登录事件
  2. 调用登录接口,将用户名和密码传递给后端
  3. 后端验证用户名和密码是否正确,如果正确则返回一个token,否则返回错误信息
  4. 前端接收到token后,将其存储在本地存储中,以便后续请求时携带
  5. 前端跳转到首页,并显示欢迎信息

(2)登录接口

  1. 登录接口需要接收用户名和密码作为参数
  2. 登录接口需要返回一个token,用于后续请求时携带

(3)登录页面

☞ 在src下面的pages里面新建一个login.vue页面

登录页面内容有:

  • 用户名
  • 密码
  • 确认密码
  • 登录按钮

☞ 配置路由

在我们的路由文件夹下面简单的添加一下我们的路由NexusVue\src\router

import { createRouter, createWebHistory, RouteRecordRaw ,createWebHashHistory} from "vue-router"; // 导入路由
// 1. 配置路由  lintaibai--进来时候的初始页面
const routes = [
    {
        path: "/", // 默认路由 home页面
        name: '/',
        component: () => import('@/views/lintaibai.vue'),
    },
    {
        path: "/login", // 默认路由 home页面
        name: 'login',
        component: () => import('@/views/admin/login.vue'),
    },

];
// 2.返回一个 router 实列,为函数,配置 history 模式
const router = createRouter({
    history: createWebHistory(), //createWebHashHistory
    routes,
});

// 3.导出路由   去 main.ts 注册 router.ts
export default router

☞ 登录代码

搭建一下我们的登录页面

先来简单搭建一下静态的登录应该是什么样子的:

// 处理表单提交的函数
    const handleSubmit = async (event) => {
        event.preventDefault();
        // 在实际应用中,这里可以发送注册请求到服务器进行用户注册
        // 这里简单地假设密码和确认密码相同才能注册成功
        if (form.value.username === '' || form.value.password === '') {
            return;
        }else{
            console.log(form.value, 'form.value');
            try {
                const res:any = await login(form.value);
              
                console.log(res,'res');
                
                if(res.code==200){
                }else{
                    // message.error(res.message);
                }
            } catch (error) {
                console.log('获取数据详情失败,请重试!',error);
            } finally {
                console.log('完!');
            }
        }
        return;
    };
<template>
    <div class="pagelogin">
        <div class="backbaige flexcenter">
            <el-form ref="loginFormRef" :model="loginForm" :rules="loginRules" class="login-form">
                <h3 class="title">后台管理系统</h3>
                <el-form-item prop="username">
                    <el-input v-model="loginForm.username" type="text" size="large" auto-complete="off" placeholder="账号">
                        <template #prefix>
                            <svg-icon icon-class="user" class="el-input__icon input-icon" /></template>
                    </el-input>
                </el-form-item>
                <el-form-item prop="password">
                    <el-input v-model="loginForm.password" type="password" size="large" auto-complete="off" placeholder="密码" @keyup.enter="handleLogin">
                        <template #prefix>
                            <svg-icon icon-class="password" class="el-input__icon input-icon" /></template>
                    </el-input>
                </el-form-item>
                <el-form-item prop="code" v-if="captchaEnabled">
                    <div style="display: flex;gap: 10px;">
                        <el-input v-model="loginForm.code" size="large" auto-complete="off" placeholder="验证码" style="width: 50%" @keyup.enter="handleLogin">
                            <template #prefix>
                                <svg-icon icon-class="validCode" class="el-input__icon input-icon" /></template>
                        </el-input>
                        <div class="login-code">
                            <img :src="codeUrl" @click="getCode" class="login-code-img" />
                        </div>
                    </div>
                </el-form-item>
                <el-form-item prop="code" v-if="showVerificationCode">
                    <el-input v-model="loginForm.code" size="large" auto-complete="off" placeholder="验证码" style="width: 50%;margin-right: 2%;" @keyup.enter="handleLogin">
                        <template #prefix>
                            <svg-icon icon-class="validCode" class="el-input__icon input-icon" /></template>
                    </el-input>
                    <div class="login-code" style="width:48%">
                        <VerificationCode style="width: 100%;height: 40px;" :length="4"></VerificationCode>
                    </div>
                </el-form-item>
                <el-checkbox v-model="loginForm.rememberMe" style="margin:0px 0px 25px 0px;">记住密码</el-checkbox>
                <el-form-item style="width:100%;">
                    <el-button :loading="loading" size="large" type="primary" style="width:100%;" @click.prevent="handleLogin">
                        <span v-if="!loading">登 录</span>
                        <span v-else>登 录 中...</span>
                    </el-button>
                    <div style="float: right;" v-if="showregister">
                        <router-link class="link-type" :to="'/register'">立即注册</router-link>
                    </div>
                </el-form-item>
            </el-form>
        </div>
    </div>
</template>
<script setup>
import { ref, reactive, toRefs, onMounted } from 'vue'
import { useRoute,useRouter } from 'vue-router'
import useUserStore from '@/store/modules/user'
import { ElMessage } from 'element-plus'
import config from '@/utils/config.js';
import { login } from '@/api/login';
import { getToken, setToken, removeToken } from '@/utils/auth'
const router = useRouter();
const route = useRoute();
const userStore = useUserStore()
const showVerificationCode = ref(true); //自定义验证码开关
// const { proxy } = getCurrentInstance();

const loginForm = ref({
    username: "admin",
    password: "admin123",
    rememberMe: false,
    code: "",
    uuid: ""
});

const loginFormRef = ref();
const loginRules = {
    username: [{ required: true, trigger: "blur", message: "请输入您的账号" }],
    password: [{ required: true, trigger: "blur", message: "请输入您的密码" }],
    code: [{ required: true, trigger: "change", message: "请输入验证码" }]
};
const codeUrl = ref("");
const loading = ref(false);

const captchaEnabled = ref(false); // 验证码开关

const showregister = ref(true); // 注册开关
const redirect = ref(undefined);

const handleLogin = async () => {
    try {
        // 校验表单
        const valid = await validateForm();
        if (!valid) {
            console.log('表单验证失败');
            return;
        }
        // console.log('表单验证', loginForm.value);
        // 调用登录接口
        const res = await login(loginForm.value);
        if (valid) {
            if(res.code==200){
                // console.log(res,'res');
                setToken(res.token);
                ElMessage.success(res.message);
                router.push({ path: "/" });
            }else{
                ElMessage.error(res.message);
            }
        } else {
            // 提示错误消息
            console.error('登录失败:');
        }
    } catch (error) {
        // 处理请求错误
        console.error('登录请求失败,错误信息:', error);
    } finally {
        // 完成后的处理逻辑
        // console.log('登录操作完成');
        // 如果需要的话,可以在这里隐藏加载动画等
    }
}

// 表单验证的异步函数
const validateForm = () => {
    return new Promise((resolve) => {
        loginFormRef.value.validate((valid, fields) => {
            if (valid) {
                resolve(true);
            } else {
                console.log('表单验证失败', fields);
                resolve(false);
            }
        });
    });
}
</script>

<style lang='scss' scoped>
.login {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100%;
    background-size: cover;
}

.title {
    margin: 0px auto 30px auto;
    text-align: center;
    color: #707070;
}

.login-form {
    border-radius: 6px;
    width: 400px;
    padding: 25px 25px 5px 25px;

    .el-input {
        height: 40px;

        input {
            height: 40px;
        }
    }

    .input-icon {
        height: 39px;
        width: 14px;
        margin-left: 0px;
    }
}

.login-tip {
    font-size: 13px;
    text-align: center;
    color: #bfbfbf;
}

.login-code {
    width: 50%;
    height: 40px;
    float: right;

    img {
        cursor: pointer;
        vertical-align: middle;
    }
}

.el-login-footer {
    height: 40px;
    line-height: 40px;
    position: fixed;
    bottom: 0;
    width: 100%;
    text-align: center;
    color: #fff;
    font-family: Arial;
    font-size: 12px;
    letter-spacing: 1px;
}

.login-code-img {
    height: 40px;
    padding-left: 12px;
}
</style>

到这里我们的登录和注册界面就好了,剩下的就是我们的优化和配置了。

最后效果如下

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。