在 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 发送登录请求,在请求发送前显示加载提示,请求完成后根据响应结果进行相应处理。登录成功时,将用户数据存储到本地,并跳转到首页;登录失败则提示用户错误信息。
四、优化与拓展方向
- 表单验证优化:可以使用更专业的表单验证库,如
vee-validate
,提升验证的灵活性和用户体验。 - 错误处理增强:对 Axios 请求的错误处理进一步细化,根据不同的错误状态码返回更友好的提示。
- 安全性提升:对密码进行加密传输,防止密码在网络传输过程中被窃取。
- 响应式设计:优化页面在不同设备上的显示效果,提升移动端体验。
通过以上步骤,我们成功构建了一个功能完整、界面美观的 Vue3 登录页面。希望本文能为你的 Vue 开发之路提供一些帮助,如果你在实践过程中有任何问题,欢迎在评论区交流讨论!