使用 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前缀
-
相关文章:
使用 Vue 开发登录页面的完整指南
一、项目搭建与基础配置 环境准备 使用 Vue CLI 或 Vite 创建项目,推荐组合:Vue3 Element Plus Vue Router npm create vuelatest npm install element-plus element-plus/icons-vue vue-router 全局配置(main.js) import { c…...
EDID结构
EDID DDC通讯中传输显示设备数据 VGA , DVI 的EDID由128字节组成,hdmi的EDID增加扩展块128字节。扩展快的内容主要是和音频属性相关的,DVI和vga没有音频,hdmi自带音频,扩展快数据规范按照cea-861x标准。 Edid为了让pc或其他的图像…...
文件包含(详解)
文件包含漏洞是一种常见的Web安全漏洞,其核心在于应用程序未对用户控制的文件路径或文件名进行严格过滤,导致攻击者能够包含并执行任意文件(包括本地或远程恶意文件)。 1. 文件包含原理 动态文件包含机制 开发者使用动态包含函数…...
《SpringBoot中@Scheduled和Quartz的区别是什么?分布式定时任务框架选型实战》
🌟 大家好,我是摘星! 🌟 今天为大家带来的是Scheduled和Quartz对比分析: 新手常见困惑: 刚学SpringBoot时,我发现用Scheduled写定时任务特别简单。但当我看到同事在项目里用Quartz时&…...
安装fvm可以让电脑同时管理多个版本的flutter、flutter常用命令、vscode连接模拟器
打开 PowerShellfvm安装 dart pub global activate fvm安装完成后,如果显示FVM无法识别,那么需要去添加环境变量path添加这个:C:\Users\Administrator\AppData\Local\Pub\Cache\bin 常用命令 fvm releases 查看用户可以装的flutter版本fvm l…...
UNION和UNION ALL的主要区别
UNION和UNION ALL的主要区别在于处理重复数据和排序的方式。 UNION和UNION ALL都是SQL语言中用于合并两个或多个SELECT语句结果集的关键字。它们的主要区别如下: 1、对重复结果的处理:UNION在进行表链接后会筛选掉重复的记录,而UNION ALL不会…...
Kafka系列之:计算kafka集群topic占的存储大小
Kafka系列之:计算kafka集群topic占的存储大小 topic存储数据格式统计topic存储大小定时统计topic存储大小topic存储数据格式 单位是字节大小 size_bytes{directory="/data/datum/kafka/optics-all" } 782336计算topic存储大小脚本逻辑是: 计算指定目录或文件的大小…...
[密码学实战]Java使用Bouncy Castle实现Base64编码解码:完整指南
Java使用Bouncy Castle实现Base64编码解码:完整指南 摘要 本文将深入讲解如何通过Bouncy Castle(BC)加密库实现Base64编码解码,包含核心API使用、流式处理、与加密算法集成三大实战场景,提供5种代码实现方案和3种性能优化技巧。 一、Base64基础原理 1.1 编码机制 Bas…...
智谱AI大模型免费开放:开启AI创作新时代
文章摘要:近日,国内领先的人工智能公司智谱AI宣布旗下多款大模型服务免费开放,这一举措标志着大模型技术正式迈入普惠阶段。本文将详细介绍智谱AI此次开放的GLM-4 等大模型,涵盖其主要功能、技术特点、使用步骤以及应用场景&#…...
为什么要给单片机植入操作系统
给单片机植入操作系统(通常是实时操作系统,RTOS)主要是为了在资源有限的环境中实现更高效、更可靠的多任务管理和系统调度。以下是主要原因和优势: 1. 多任务并行处理 背景:单片机通常需要同时处理多个任务࿰…...
T1结构像+RS-fMRI影像处理过程记录(数据下载+Matlab工具箱+数据处理)
最近需要仿真研究T1结构像RS-fMRI影像融合处理输出目标坐标的路线可行性。就此机会记录下来。 为了完成验证目标处理,首先需要有数据,然后需要准备对应的处理平台和工具箱,进行一系列。那么开始记录~ 前言: 为了基于种子点的功能连…...
【前端基础】--- HTML
个人主页 : 9ilk 专栏 : 前端基础 文章目录 🏠 初识HTML🏠 HTML结构认识HTML标签HTML文件基本结构标签层次结构快速生成代码框架 🏠 HTML常见标签注释标签标题标签 h1-h6段落标签 p换行标签 br格式化标签图片标签 img超链接标签…...
黑马V11版 最新Java高级软件工程师课程-JavaEE精英进阶课
课程大小:60.2G 课程下载:https://download.csdn.net/download/m0_66047725/90615581 更多资源下载:关注我 阶段一 中台战略与组件化开发专题课程 阶段二 【物流行业】品达物流TMS 阶段三 智牛股 阶段四 千亿级电商秒杀解决方案专题 …...
C#插件与可扩展性
外接程序为主机应用程序提供了扩展功能或服务。.net framework提供了一个编程模型,开发人员可以使用该模型来开发加载项并在其主机应用程序中激活它们。该模型通过在主机和外接程序之间构建通信管道来实现此目的。该模型是使用: System.AddIn, System.AddIn.Hosting, System.…...
CVPR‘25 | 高文字渲染精度的商品图文海报生成
本文分享阿里妈妈智能创作与AI应用团队在图文广告创意方向上提出的商品图文海报生成模型,通过构建字符级视觉表征作为控制信号,可以实现精准的图上中文逐像素生成。基于该项工作总结的论文已被 CVPR 2025录用,并在阿里妈妈业务场景落地&#…...
Golang|抽奖相关
文章目录 抽奖核心算法生成抽奖大转盘抽奖接口实现 抽奖核心算法 我们可以根据 单商品库存量/总商品库存量 得到每个商品被抽中的概率,可以想象这样一条 0-1 的数轴,数轴上的每一段相当于一种商品,概率之和为1。 抽奖时,我们会生…...
RT-Thread开发文档合集
瑞萨VisionBoard开发实践指南 RT-Thread 文档中心 RT-Thread-【RA8D1-Vision Board】 RA8D1 Vision Board上的USB实践RT-Thread问答社区 - RT-Thread 【开发板】环境篇:05烧录工具介绍_哔哩哔哩_bilibili 【RA8D1-Vision Board】基于OpenMV 实现图像分类_哔哩哔哩_…...
rulego-server是一个开源程序,是一个轻量级、无依赖性的工作流自动化平台。支持 iPaaS、流式计算和 AI 能力。
一、软件介绍 文末提供程序和源码下载学习 RuleGo-Server 是一个基于 RuleGo 构建的轻量级、高性能、模块化和集成友好的自动化工作流程平台。可用于自动化编排、iPaaS(集成平台即服务)、API 编排、应用编排、AI 编排、数据处理、IoT 规则引擎、AI 助手…...
鸿蒙系统开发状态更新字段区别对比
在鸿蒙系统开发中,状态管理是构建响应式UI的核心机制,主要通过装饰器(Decorators)实现字段的状态观测与更新。根据鸿蒙的版本(V1稳定版和V2试用版),支持的装饰器及其特性有所不同。以下是主要状…...
抽象的https原理简介
前言 小明和小美是一对好朋友,他们分隔两地,平时经常写信沟通,但是偶然被小明发现他回给小美的信好像被人拆开看过,甚至偷偷被篡改过。 对称加密算法 开头的通信过程比较像HTTP服务器与客户端的通信过程,全明文传输…...
HTML理论题
1.什么是HTML? 超文本标记语言(英语:HyperText Markup Language,简称:HTML)是一种用于创建网页的标准标记语言。 2.DOCTYPE 的作用是什么?标准与兼容模式(混杂模式)各有什么区别? DOCTYPE 的作用是告知浏览器的解析器用什么文档标准解析这个文档。 标准模式:用于…...
nginx-基础知识(二)
目录 虚拟主机 虚拟主机的功能 虚拟主机的划分方式 基于IP地址进行划分 基于域名进行划分 正向/反向代理 正向代理 反向代理 正向代理和反向代理的区别 负载均衡 负载均衡的类型 负载均衡的作用 nginx并发量比较高的原因 负载均衡的算法 会话保持 虚拟主机 虚拟…...
Ubuntu上安装Mysql
步骤 1:安装 MySQL Server sudo apt update sudo apt install mysql-server -y这将安装最新版本的 MySQL 8.0 以及所有依赖组件。 步骤 2:检查安装是否成功 mysql --version sudo systemctl status mysql如果状态是 active (running),说明成…...
idea maven 命令后控制台乱码
首先在idea中查看maven的编码方式 执行mvn -v命令 查看编码语言是GBK C:\Users\13488>mvn -v Apache Maven 3.6.3 (cecedd343002696d0abb50b32b541b8a6ba2883f) Maven home: D:\maven\apache-maven-3.6.3\bin\.. Java version: 1.8.0_202, vendor: Oracle Corporation, runt…...
C# dll 打包进exe
Framework4.x推荐使用 Costura.Fody 1. 安装 NuGet 包 Install-Package Costura.Fody工程自动生成packages文件夹,300M左右。生成FodyWeavers.xml、FodyWeavers.xsd文件。 2. 自动嵌入 编译后,所有依赖的 DLL 会被自动嵌入到 EXE 中。 运行时自动解压…...
【数据融合实战手册·实战篇】二维赋能三维的5种高阶玩法:手把手教你用Mapmost打造智慧城市标杆案例
在当今数字化时代,二三维数据融合技术的重要性不言而喻。二三维数据融合通过整合二维数据的结构化优势与三维数据的直观性,打破了传统数据在表达和分析上的局限,为各行业提供了更全面、精准的数据分析手段。从智慧城市建设到工业智能制造&…...
ValueError: model.embed_tokens.weight doesn‘t have any device set
ValueError: model.embed_tokens.weight doesn’t have any device set model.embed_tokens.weight 通常在深度学习框架(如 PyTorch)中使用,一般是在处理自然语言处理(NLP)任务时,用于指代模型中词嵌入层(Embedding layer)的权重参数。下面详细解释: 词嵌入层的作用 …...
解决:QTcpSocket: No such file or directory
项目场景: 使用QTcpSocket进行网络编程: 调用connectToHost连接服务器,调用waitForConnected判断是否连接成功,连接信号readyRead槽函数,异步读取数据,调用waitForReadyRead,阻塞读取数据。 问题描述 找不…...
六、LangChain Agent 最佳实践
1. 架构设计与组件选择 (1) 核心组件分层设计 Model(LLM驱动层) 生产环境推荐:使用 gpt-4-1106-preview 或 Anthropic Claude 3 等高性能模型,结合 model.with_fallbacks() 实现故障转移(如备用模型或本地模型)。本地部署:选择 Llama3-70B 等开源模型,搭配 Docker 或 …...
uni-app 安卓10以上上传原图解决方案
在Android 10及以上版本中,由于系统对文件访问的限制,使用chooseImage并勾选原图上传后,返回的是图片的外部存储路径,如:file:///storage/emulated/0/DCIM/Camera/。这种外部存储路径,无法直接转换成所需要…...
