从零构建 Vue3 登录页:结合 Vant 组件与 Axios 实现完整登录功能

发布于:2025-04-19 ⋅ 阅读:(22) ⋅ 点赞:(0)

在 Web 开发的世界里,登录页是用户与应用交互的第一道门槛,它的体验好坏直接影响着用户对整个应用的印象。本文将详细记录如何使用 Vue3、Vant 组件库和 Axios 构建一个兼具美观与实用的登录页面,并实现完整的登录逻辑与数据验证,带你一步步打造一个高质量的登录功能。

一、项目初始化与技术栈选择

本次项目基于 Vue3 进行开发,Vue3 以其高效的响应式系统和组合式 API,极大地提升了代码的可读性和可维护性。同时引入 Vant 组件库,它提供了丰富的移动端组件,方便快速搭建界面;Axios 则用于处理 HTTP 请求,与后端进行数据交互。

首先,确保本地已安装 Node.js 环境,使用以下命令创建一个新的 Vue3 项目:

npm init vue@latest

按照提示完成项目初始化,进入项目目录并安装 Vant 和 Axios: 

cd your-project-name
npm install vant axios

main.js中引入 Vant 组件和样式: 

 

import { createApp } from 'vue';
import App from './App.vue';
import Vant from 'vant';
import 'vant/lib/index.css';

const app = createApp(App);
app.use(Vant);
app.mount('#app');

二、页面布局与样式设计

登录页面的布局通过 HTML 模板和 CSS 样式来实现。整体页面结构如下:

<template>
    <div class="login_box">
        <img src="../assets/aircraft.png" alt="" class="aircraft" />
        <div class="login_form">
            <input placeholder="请输入手机号" v-model="phone" class="phone" />
            <input placeholder="请输入密码" v-model="password" class="password" type="password" />
            <div class="auth_links">
                <div class="user_agreement">
                    <van-checkbox-group v-model="checked" shape="square">
                        <van-checkbox name="a">
                            <div class="agreement">用户协议</div>
                        </van-checkbox>
                    </van-checkbox-group>
                </div>
                <div class="forget_password">
                    <div class="forget">忘记密码?</div>
                    <div class="forget">前往注册</div>
                </div>
            </div>
            <van-button type="warning" class="publish" @click="login">登录</van-button>
        </div>

        <img src="../assets/WeChat.png" alt="" class="img_WeChat">
        <!-- 底部标识 -->
        <div class="sign">
            @版权归大喇叭编程实训基地所有
        </div>
    </div>
</template>

CSS 样式部分通过<style scoped>标签实现样式作用域隔离,保证样式仅作用于当前组件 

<style scoped>
* {
    margin: 0;
    padding: 0;
}

.login_box {
    width: 100%;
    height: 100vh;
    background-image: url('../assets/login_back.png');
    background-size: cover;
}

.aircraft {
    width: 50%;
    position: absolute;
    top: 10%;
    left: 15%;
}

.login_form {
    width: 90%;
    height: 260px;
    position: absolute;
    top: 30%;
    left: 5%;
    background-color: rgba(255, 255, 255, 0.5);
    border-radius: 10px;
}

.publish {
    width: 95%;
    height: 50px;
    position: absolute;
    bottom: 10px;
    left: 2.5%;
    border-radius: 10px;
    background-color: rgba(42, 130, 228, 1);
    color: #fff;
    font-size: 18px;
    text-align: center;
    line-height: 50px;
    border: none;
}

.phone {
    width: 90%;
    height: 40px;
    top: 15%;
    left: 5%;
    border-radius: 3px;
    background-color: rgb(255, 255, 255);
    text-indent: 5px;
    margin-left: 5%;
    margin-top: 20px;
    border: none;
}

/* 新增密码输入框的样式 */
.password {
    width: 90%;
    height: 40px;
    top: 15%;
    left: 5%;
    border-radius: 3px;
    background-color: rgb(255, 255, 255);
    text-indent: 5px;
    margin-left: 5%;
    margin-top: 20px;
    border: none;
}

.auth_links {
    width: 90%;
    height: 40px;
    margin-left: 5%;
    margin-top: 10px;
    display: flex;
    justify-content: space-between;
}

#agreement_box {
    width: 18px;
    height: 18px;
    margin-top: 10px;
    margin-left: 5px;
}

.user_agreement {
    display: flex;
}

.agreement {
    line-height: 40px;
    font-size: 14px;
    color: rgba(42, 130, 228, 1);
}

.forget {
    line-height: 40px;
    margin-right: 20px;
    font-size: 14px;
    color: rgba(42, 130, 228, 1);
}

.forget_password {
    display: flex;
}

.img_WeChat {
    width: 50px;
    height: 50px;
    position: fixed;
    bottom: 20%;
    left: 45%;
}

.sign {
    width: 100%;
    height: 30px;
    position: fixed;
    bottom: 13%;
    color: rgba(80, 80, 80, 1);
    text-align: center;
    line-height: 30px;
}
</style>

上述代码中,.login_box设置了背景图片,作为整个登录页的背景;.login_form包裹了输入框、协议选择和登录按钮,通过定位和样式设置,使其在页面中居中显示;输入框和按钮使用了简单的样式设计,保证清晰易用。

三、登录逻辑与数据验证

<script setup>中实现登录逻辑和数据验证。首先引入必要的 Vue 和 Axios 相关模块:

import { useRouter, useRoute } from "vue-router";
import { ref } from "vue";
import { onMounted, onUnmounted } from 'vue';

import axios from "axios";
import { showToast } from 'vant';

定义响应式数据,用于存储手机号、密码和协议勾选状态: 

const router = useRouter();
const route = useRoute();

const phone = ref("");
const password = ref("");
const checked = ref();

核心的登录函数login实现了完整的登录逻辑:

const login = async () => {
    try {
        // 验证手机号
        if (!phone.value) {
            return showToast({ message: '请输入手机号', position: 'top' });
        }

        if (!/^1[3-9]\d{9}$/.test(phone.value)) {
            return showToast({ message: '请输入正确的手机号', position: 'top' });
        }

        // 验证密码
        if (!password.value) {
            return showToast({ message: '请输入密码', position: 'top' });
        }

        if (password.value.length < 6 || password.value.length > 18) {
            return showToast({ message: '密码长度必须在6-18之间', position: 'top' });
        }

        // 验证用户协议
        if (!checked.value || !checked.value.length) {
            return showToast({ message: '请阅读并同意用户协议', position: 'top' });
        }

        // 添加加载状态
        const loadingToast = showToast({
            message: '登录中...',
            position: 'top',
            duration: 0,
            forbidClick: true
        });

        // 发送登录请求
        const response = await axios.post('登录接口地址', {
            tel: phone.value,
            pass: password.value
        });

        // 关闭加载提示
        loadingToast.close();

        // 处理响应
        if (response.data.code === 1) {
            showToast({ message: '登录成功', position: 'top' });

            // 打印返回的数据
            console.log('登录成功,返回数据:', response.data);

            // 如果需要,可以将数据存储到本地
            sessionStorage.setItem('userData', JSON.stringify(response.data));

            router.push({ name: 'home' });
        } else {
            console.log('登录失败,返回数据:', response.data);
            showToast({ message: response.data.msg || '登录失败', position: 'top' });
        }
    } catch (error) {
        // 关闭加载提示
        if (loadingToast) loadingToast.close();

        console.error('登录出错:', error);
        showToast({
            message: error.response?.data?.message || '网络错误,请重试',
            position: 'top'
        });
    }
}

在登录函数中,首先对手机号、密码和用户协议进行严格验证,确保用户输入的数据符合要求。然后通过 Axios 发送登录请求,在请求发送前显示加载提示,请求完成后根据响应结果进行相应处理。登录成功时,将用户数据存储到本地,并跳转到首页;登录失败则提示用户错误信息。

四、优化与拓展方向

  1. 表单验证优化:可以使用更专业的表单验证库,如vee-validate,提升验证的灵活性和用户体验。
  2. 错误处理增强:对 Axios 请求的错误处理进一步细化,根据不同的错误状态码返回更友好的提示。
  3. 安全性提升:对密码进行加密传输,防止密码在网络传输过程中被窃取。
  4. 响应式设计:优化页面在不同设备上的显示效果,提升移动端体验。

通过以上步骤,我们成功构建了一个功能完整、界面美观的 Vue3 登录页面。希望本文能为你的 Vue 开发之路提供一些帮助,如果你在实践过程中有任何问题,欢迎在评论区交流讨论!


网站公告

今日签到

点亮在社区的每一天
去签到