使用 Vue 开发登录页面的完整指南
一、项目搭建与基础配置
-
环境准备
使用 Vue CLI 或 Vite 创建项目,推荐组合:Vue3 + Element Plus + Vue Routernpm create vue@latest npm install element-plus @element-plus/icons-vue vue-router
-
全局配置(main.js)
import { createApp } from 'vue' import ElementPlus from 'element-plus' import router from './router' import 'element-plus/dist/index.css'const app = createApp(App) app.use(ElementPlus) app.use(router) app.mount('#app')
二、登录页面核心实现
-
模板结构(login.vue)
<template><div class="login-container"><el-form ref="formRef" :model="form" :rules="rules"><h2 class="title">校园交易平台</h2><el-form-item prop="username"><el-inputv-model="form.username"prefix-icon="User"placeholder="请输入手机号"/></el-form-item><el-form-item prop="password"><el-inputv-model="form.password"prefix-icon="Lock"type="password"show-passwordplaceholder="请输入密码"@keyup.enter="handleLogin"/></el-form-item><el-button type="primary" :loading="loading"@click="handleLogin">登录</el-button><div class="links"><router-link to="/register">立即注册</router-link><router-link to="/forgot">忘记密码?</router-link></div></el-form></div> </template>
-
数据与验证逻辑
<script setup> import { ref, reactive } from 'vue' import { useRouter } from 'vue-router' import { ElMessage } from 'element-plus'const form = reactive({username: '',password: '' })const rules = reactive({username: [{ required: true, message: '请输入手机号', trigger: 'blur' },{ pattern: /^1[3-9]\d{9}$/, message: '手机号格式错误' }],password: [{ required: true, message: '请输入密码', trigger: 'blur' },{ min: 6, max: 16, message: '长度6-16位' }] })const loading = ref(false) const formRef = ref(null) const router = useRouter()const handleLogin = async () => {try {await formRef.value.validate()loading.value = true// 模拟API请求await new Promise(resolve => setTimeout(resolve, 1000))sessionStorage.setItem('token', 'demo_token')ElMessage.success('登录成功')router.replace('/dashboard')} catch (error) {console.error('登录失败:', error)} finally {loading.value = false} } </script>
-
样式优化要点
<style scoped> .login-container {height: 100vh;display: grid;place-items: center;background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%); }.title {text-align: center;margin-bottom: 2rem;color: #2c3e50;font-size: 1.8rem; }:deep(.el-form) {width: 400px;padding: 2rem;background: rgba(255,255,255,0.95);border-radius: 12px;box-shadow: 0 4px 20px rgba(0,0,0,0.1); }.el-button {width: 100%;margin-top: 1rem; }.links {margin-top: 1.5rem;display: flex;justify-content: space-between;a {color: #409eff;text-decoration: none;transition: color 0.3s;&:hover {color: #66b1ff;}} } </style>
三、进阶功能实现
-
路由守卫配置
// router/index.js router.beforeEach((to) => {const isAuthenticated = sessionStorage.getItem('token')if (to.meta.requiresAuth && !isAuthenticated) {return '/login'}if (to.path === '/login' && isAuthenticated) {return '/dashboard'} })
-
安全增强方案
-
密码加密传输(使用crypto-js)
-
添加验证码功能
-
请求限流与防重放攻击
import CryptoJS from 'crypto-js'const encryptPassword = (password) => {return CryptoJS.SHA256(password).toString() }
-
-
第三方登录集成
<template><div class="oauth-login"><el-divider>第三方登录</el-divider><div class="oauth-buttons"><el-button @click="handleWechatLogin"><svg-icon icon-class="wechat" />微信登录</el-button></div></div> </template>
四、最佳实践与注意事项
-
表单验证优化
-
异步验证手机号是否注册
-
密码强度实时检测
const checkUsername = async (rule, value, callback) => {if (!value) return callback(new Error('请输入手机号'))if (!/^1[3-9]\d{9}$/.test(value)) return callback(new Error('格式错误'))try {const { data } = await api.checkUsername(value)if (!data.exist) callback(new Error('该用户未注册'))} catch (error) {callback(new Error('验证失败'))} }
-
-
用户体验优化
-
自动填充最近登录账号
-
记住密码功能(加密存储)
-
加载状态管理
// 自动填充 const lastUsername = localStorage.getItem('lastUsername') if (lastUsername) form.username = lastUsername// 记住密码 const savePassword = ref(false) watch(savePassword, (val) => {if (val) {localStorage.setItem('remembered', JSON.stringify(form))} else {localStorage.removeItem('remembered')} })
-
-
错误处理规范
try {const res = await loginApi(formData)if (res.code === 1001) {ElMessage.warning('该账号已被冻结')} } catch (err) {ElMessage.error({message: `登录失败: ${err.message}`,grouping: true // 相同错误合并显示}) }
五、典型问题解决方案
-
跨域问题处理
// vite.config.js export default defineConfig({server: {proxy: {'/api': {target: 'http://backend.example.com',changeOrigin: true,rewrite: (path) => path.replace(/^\/api/, '')}}} })
-
响应式布局适配
@media (max-width: 768px) {.login-container {padding: 1rem;:deep(.el-form) {width: 100%;margin: 0 1rem;}} }
-
浏览器兼容问题
-
使用@vitejs/plugin-legacy处理ES6+语法
-
添加autoprefixer自动补全CSS前缀
-