vue3+ts+elementplus写一个登录页面教程

news2024/11/24 13:08:56

在这里插入图片描述

文章目录

  • 前言
    • 1. 安装 Vue CLI 和 TypeScript 支持
      • 2. 创建登录组件
  • 文章重点内容


前言

前期准备步骤:
创建一个使用 Vue 3 和 TypeScript 的登录页面涉及到多个步骤。以下是一个基本的教程,帮助你从头开始构建这样一个页面:

1. 安装 Vue CLI 和 TypeScript 支持

首先,你需要安装 Vue CLI 并配置它以支持 TypeScript。如果你还没有安装 Vue CLI,可以通过以下命令进行安装:

npm install -g @vue/cli  
# OR  
yarn global add @vue/cli

然后,你可以创建一个新的 Vue 3 项目并启用 TypeScript 支持:

vue create my-login-app

在创建过程中,选择 “Manually select features”,然后勾选 “TypeScript” 和其他你需要的特性(比如 Router、Linter/Formatter 等)。

2. 创建登录组件

在 src/views目录下创建一个新的 TypeScript 文件,比如 Login.vue。这个文件将包含你的登录表单和逻辑。

文章重点内容

页面样式:
在这里插入图片描述
页面代码:

		<div class="login-right-warp">
				<div class="login-right-warp-title">login</div>
				<div class="login-right-warp-form">
					<div class="login-right-warp-form_title">用户名登录</div>

					<el-form ref="ruleFormRef" style="max-width: 600px" :model="ruleForm" status-icon :rules="rules"
						label-width="auto" class="demo-ruleForm">
						<el-form-item prop="AccountNo">
							<el-input v-model="ruleForm.AccountNo" autocomplete="off" :prefix-icon="User"
								placeholder="请输入账号" />
						</el-form-item>
						<el-form-item prop="AccountPwd">
							<el-input v-model="ruleForm.AccountPwd" type="password" autocomplete="off" :prefix-icon="Lock"
								placeholder="请输入密码" />
						</el-form-item>
						<el-form-item prop="Code">
							<el-input v-model.number="ruleForm.Code" :prefix-icon="Promotion" class="login-content-code"
								placeholder="请输入验证码" />
							<span class="login-content-code-img" @click="generateCodeAsync()">{{ verificationCode.Code
							}}</span>
						</el-form-item>
						<el-form-item>
							<el-button type="primary" @click="submitForm(ruleFormRef)">登录</el-button>
						</el-form-item>
					</el-form>
					<div class="login-msg">* 温馨提示:建议使用谷歌、Microsoft Edge,版本 79.0.1072.62 及以上浏览器,360浏览器请使用极速模式</div>
				</div>
			</div>

script代码:

import { reactive, onMounted, ref } from 'vue';
import type { FormInstance, FormRules } from 'element-plus';
import { User, Lock, Promotion } from '@element-plus/icons-vue';
import { postLoginAsync, postGenerateCodeAsync } from '@/api/login';
import { useRouter } from 'vue-router';

// 使用 Vue Router 的 useRouter 函数来获取 router 实例
const router = useRouter();

const ruleFormRef = ref<FormInstance>();

// 页面加载时
onMounted(() => {
	generateCodeAsync();
});

const validateCodeKey = (rule: any, value: any, callback: any) => {
	if (value === '') {
		callback(new Error('请输入验证码'));
	} else {
		callback();
	}
};

const validateAccountNo = (rule: any, value: any, callback: any) => {
	if (value === '') {
		callback(new Error('请输入账号'));
	} else {
		callback();
	}
};
const validateAccountPwd = (rule: any, value: any, callback: any) => {
	if (value === '') {
		callback(new Error('请输入密码'));
	} else {
		callback();
	}
};

const ruleForm = reactive({
	AccountNo: '123',
	AccountPwd: '',
	CodeKey: '',
	Code: '',
});

const verificationCode = reactive({
	CodeKey: '',
	Code: '',
});



const rules = reactive<FormRules<typeof ruleForm>>({
	AccountNo: [{ validator: validateAccountNo, trigger: 'blur' }],
	AccountPwd: [{ validator: validateAccountPwd, trigger: 'blur' }],
	Code: [{ validator: validateCodeKey, trigger: 'blur' }],
});
const generateCodeAsync = () => {
	postGenerateCodeAsync().then((res: any) => {
		verificationCode.Code = res.Data.Code;
		verificationCode.CodeKey = res.Data.Key;
		ruleForm.CodeKey = res.Data.Key;
	});
};

const submitForm = (formEl: FormInstance | undefined) => {
	if (!formEl) return;
	formEl.validate((valid) => {
		if (valid) {
			console.log('submit!');
			router.push('/home');
		} else {
			console.log('error submit!');
			return false;
		}
	});
};
</script>

样式代码:

.login {
	width: 100vw;
	height: 100vh;
	background: #fff;

	.login-left {
		.login-left-logo {
			display: flex;
			align-items: center;
			position: absolute;
			top: 50px;
			left: 80px;
			z-index: 1;
			animation: logoAnimation 0.3s ease;

			img {
				width: 100px;
				height: 64px;
			}

			.login-left-logo-text {
				display: flex;
				flex-direction: column;
			}

			.login-left-logo-text span {
				margin-left: 10px;
				font-size: 30px;
				font-weight: 700;
				color: #de2910;
			}

			.login-left-logo-text .login-left-logo-text-msg {
				font-size: 12px;
				color: #de2910;
			}
		}

		.login-left-img {
			width: 90%;
			margin: 70px 0 0px 10%;
			height: 90%;
			min-height: 500px;
			min-width: 500px;
			display: flex;
			justify-content: center;
			align-items: center;

			img {
				height: 500px;
				min-width: 500px;
			}
		}
	}

	.login-right {
		width: 650px;

		.login-right-warp {
			border: 1px solid #e76959;
			border-radius: 3px;
			width: 500px;
			height: 550px;
			position: relative;
			overflow: hidden;
			background-color: #fff;
			margin: auto;

			.login-right-warp-title {
				height: 130px;
				line-height: 130px;
				font-size: 32px;
				font-weight: 800;
				text-align: center;
				animation: logoAnimation 0.3s ease;
				animation-delay: 0.3s;
				color: #f00;
			}

			.login-right-warp-form {
				padding: 0 50px 50px;
			}

			.login-right-warp-form_title {
				color: #de2910;
				width: 100%;
				padding: 10px 0px;
				border-bottom: 1px solid #e4e7ed;
				position: relative;
			}

			.login-right-warp-form_title::after {
				content: '';
				position: absolute;
				width: 90px;
				height: 2px;
				background: #de2910;
				bottom: 0;
				left: 0px;
			}
		}

		.el-form {
			margin-top: 30px;
		}

		.el-input {
			width: 100%;
			height: 40px;
		}

		.el-button {
			width: 100%;
			height: 40px;
			border-radius: 20px;
			background: #de2910;
			border: #de2910;
			margin: 20px 0px;
		}

		.login-content-code {
			width: 70%;
		}

		.login-content-code-img {
			width: 25%;
			background-color: #fff;
			border: 1px solid rgb(220, 223, 230);
			height: 38px;
			border-radius: 5px;
			margin-left: 4.5%;
			line-height: 38px;
			text-align: center;
			cursor: pointer;
		}

		.login-msg {
			margin-top: 30px;
			color: #a8abb2;
			font-size: 12px;
		}
	}
}

您好,我是肥晨。
欢迎关注我获取前端学习资源,日常分享技术变革,生存法则;行业内幕,洞察先机。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1545983.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

电路笔记 :灯光画 元器件焊接+连锡处理

https://oshwhub.com/qazwsx1987/dengguanghua_0#P3 基础工具 常用的电路焊接工具&#xff1a; 工具描述电烙铁我买了一个便携电烙铁&#xff0c;但是烙铁头温度太低&#xff0c;焊锡总是粘在烙铁头上&#xff08;因为电量不足&#xff09;, 打火机秒变电烙铁焊台用于支撑工…

突破创作瓶颈:Kompas.ai的创意激发法

在创作的世界里&#xff0c;灵感如同一股清泉&#xff0c;滋养着每一个创作者的心灵。然而&#xff0c;即便是最富创造力的头脑&#xff0c;也难免会遇到创作瓶颈——那些令人窒息的、灵感枯竭的时刻。这些瓶颈不仅阻碍了创作的进程&#xff0c;还可能严重影响内容的质量和创作…

程序员35岁会失业吗?【来自主流AI的回答】

程序员35岁会失业吗&#xff1f; 35岁被认为是程序员职业生涯的分水岭&#xff0c;许多程序员开始担忧自己的职业发展是否会受到年龄的限制。有人担心随着年龄的增长&#xff0c;技术更新换代的速度会使得资深程序员难以跟上&#xff1b;而另一些人则认为&#xff0c;丰富的经…

卷起来——高级数据分析师

要成为一名高级数据分析师&#xff0c;需要掌握一系列的技能&#xff0c;包括数据处理、统计分析、机器学习、数据可视化以及业务理解等&#xff0c;喜欢或者想往这方面发展的童鞋们&#xff0c;卷起来&#xff0c;点击以下链接中的链接&#xff0c;备注"分析"进群交…

MySQL事务(超详细!!!)

目录 一、MySQL事务的概念 二、事务的ACID特点 1、原子性&#xff08;Atomicity&#xff09; 2、持久性 3、隔离性&#xff08;Isolation&#xff09; 3.1 事务的并发问题 ①、脏读(读取未提交数据) ②读已提交、不可重复读(前后多次读取&#xff0c;数据内容不一致) …

深入探讨Maven打包:打造精致的Zip包

在部署Spring Boot生产项目时&#xff0c;首先需要使用Maven将其打包成一个JAR文件或者包含JAR文件的ZIP文件。随后&#xff0c;通过堡垒机将打包好的文件上传至服务器进行部署&#xff0c;或构建成Docker镜像进行发布。在这一过程中&#xff0c;我们需要将项目中的配置文件或静…

I.MX6ULL_Linux_驱动篇(56)linux PWM驱动

PWM 驱动简析 设备树 PWM 控制器节点 I.MX6ULL 有 8 路 PWM 输出&#xff0c;因此对应 8 个 PWM 控制器&#xff0c;所有在设备树下就有 8 个PWM 控制器节点。这 8 路 PWM 都属于 I.MX6ULL 的 AIPS-1 域&#xff0c;但是在设备树 imx6ull.dtsi 中分为了两部分&#xff0c; PW…

科技引领趋势:3D元宇宙展厅在各行业中的应用及其未来展望

随着技术的不断进步&#xff0c;3D元宇宙展厅正逐渐成为各行各业展示产品的新选择。相较于传统的线下展厅&#xff0c;3D元宇宙展厅以其独特的优势&#xff0c;为产品展示和品牌推广提供了全新的可能性。 一、虚拟与现实的完美融合 3D元宇宙展厅是指在虚拟世界中构建的三维展览…

提升质量透明度,动力电池企业的数据驱动生产实践 | 数据要素 × 工业制造

系列导读 如《“数据要素”三年行动计划&#xff08;2024—2026年&#xff09;》指出&#xff0c;工业制造是“数据要素”的关键领域之一。如何发挥海量数据资源、丰富应用场景等多重优势&#xff0c;以数据流引领技术流、资金流、人才流、物资流&#xff0c;对于制造企业而言…

一身素衣凭栏观景,携几缕清风伴皓月入梦

这个国风两件套真的很难不爱一套上身简直就是梦中的白月光素净优雅又不失清冷气质波浪型门襟绣加上花枝缠绕的绣花图案增添了设计感的同时又不失美感半裙做的是A摆小伞裙的版型裙摆的分割和收褶处理增加了层次感半裙里布很贴心的做了裤里&#xff0c;不易走光夏天穿上这套出街一…

JavaScript 学习日记(1)---初识JavaScript

初识JavaScript 文章目录 初识JavaScript一、JavaScript 是什么?二、java 和JavaScript 的关系三、JavaScript 的组成四、JS的基本输入输出 ---> 单行注释五、js变量基本概念六、js基本数据类型七、js转义字符八、js类型转换九、运算符 END! 一、JavaScript 是什么? 我们…

ESCTF赛题WP

ESCTF_reverse题解 逆吧腻吧babypybabypolyreeasy_rere1你是个好孩子完结撒花 Q_W_Q 逆吧腻吧 下载副本后无壳&#xff0c;直接拖入ida分析分析函数逻辑&#xff1a;ida打开如下&#xff1a;提取出全局变量res的数据后&#xff0c;编写异或脚本进行解密&#xff1a; a[0xBF, …

Canine IP-10/CXCL 10 ELISA试剂盒上新

科研用Canine IP-10/CXCL 10 ELISA试剂盒重磅来袭&#xff0c;将在免疫学、癌症研究与神经科学等多个领域助力各位老师们的研究&#xff01; 图1&#xff1a;犬IP-10/CXCL10结构预测&#xff08;图片来源&#xff1a;UniProt&#xff09; C-X-C基序趋化因子(C-X-C motif chemok…

Ubuntu安装教程——Desktop版本(细致入微的操作)

目录 前言 一、安装Ubuntu桌面版操作系统 二、UbuntuLive版安装 1.语言选择 2.键盘布局 3.版本选择 4.网络配置 5.代理配置 6.镜像地址 7.磁盘划分 8.设置用户信息 9.ssh 10.选择软件包 11.安装界面 12.基础配置 12.1root用户 12.2时区 12.3包管理工具 12…

慧天[HTWATER]与主流耦合模拟软件模拟结果都对比

慧天[HTWATER]软件简介 针对城市排水系统基础设施数据管理的需求&#xff0c;以及水文、水力及水质模拟对数据的需求&#xff0c;实现了以数据库方式对相应数据的存储。可以对分流制排水系统及合流制排水系统进行地表水文、管网水力、水质过程的模拟计算。可以对城市低影响开发…

基于springboot+vue+Mysql的校园博客系统

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…

数据结构从入门到精通——归并排序

归并排序 前言一、归并排序的基本思想二、归并排序的特性总结三、归并排序的动画展示四、递归实现归并排序的具体代码展示五、非递归实现归并排序 前言 归并排序是一种分治策略的排序算法。它将一个序列分为两个等长&#xff08;几乎等长&#xff09;的子序列&#xff0c;分别…

Linux--Flappy_bird实现

目录 void handler(int sig): mian: void init_curses() int set_timer(int ms_t); 小鸟的操作&#xff1a; void show_pipe()&#xff1a; void create_list() void clear_pipe() void move_pipe(); test_bird.c完整代码&#xff1a; 代码实现&#xff1a; #includ…

动归专题——斐波纳契模型和路径问题

前提 本专题开始&#xff0c;注重整理与动态规划相关的题目&#xff0c;从简单的动归开始切入&#xff0c;慢慢掌握和练习动态规划这一重要的算法思想&#xff0c;部分相对复杂的题目会结合画图和代码分析去解释 一、第N个泰波纳契数列 1.链接 1137. 第 N 个泰波那契数 - 力…