vue中实现数字+英文字母组合键盘

news2024/11/30 9:34:57

  完整代码

<template>
	<div class="login">
        <div @click="setFileClick">欢迎使用员工自助终端</div>
		<el-dialog title="初始化设置文件打印消耗品配置密码" :visible.sync="dialogSetFile" width="600px">
			<el-form :model="fileForm" ref="fileForm" status-icon label-width="100px">
				<el-form-item label="密码" prop="password">
					<el-input type="password" v-model="fileForm.password" show-password @focus="ifWritePopUp = true"></el-input>
				</el-form-item>
				<div class="screen-sign-mid" style="display: none;">
					<div class="screen-sign-mid-inner">
						<input class="self-el-input" type="text" v-model="password" ref="passwordInput" />
						<button class="self-el-button" type="button" @click.stop="checkIn()">确认</button>
					</div>
				</div>
				<!-- 键盘组件开始 -->
				<div class="keyboard-wrap" v-show="ifWritePopUp">
				  <div class="key-group-item" v-for="(keyItem, index) in keyList" :key="index">
					<div class="key-item" :style="item.type == 'letter' ? '' : 'width:135px;'" v-for="(item, index) in keyItem" :key="index" :data-type="item.type" @click.stop="keyboardClick">
					  <span class="vertical-center">{{ item.text }}</span>
					</div>
				  </div>
				</div>

				<div style="text-align: center;">
				    <el-button type="primary" @click="submitForm" icon="el-icon-check">提交</el-button>
					<el-button @click="resetForm" icon="el-icon-delete">重置</el-button>
				</div>
			</el-form>
		</el-dialog>
	</div>
</template>
<script>
	import { queryInitializeFile, initPassword } from "@/api/setFile";
	
	export default {
		data() {
			return {
				clickCount: 0, //点击次数
				dialogSetFile: false, //初始化文件配置
				ifInitialize: '', //是否初始化
				fileForm: {
					password: '',
				},
				ifWritePopUp: false,
				password: "", //键盘输入内容
				keyList: [
					// 键盘布局
					[{ text: "1",type: "digit"},{ text: "2",type: "digit"},
					 { text: "3",type: "digit"},{ text: "4",type: "digit"},
					 { text: "5",type: "digit"},{ text: "6",type: "digit"},
					 { text: "7",type: "digit"},{ text: "8",type: "digit"},
					 { text: "9",type: "digit"},{ text: "0",type: "digit"}],
					[{text: "Q",type: "digit"},{text: "W",type: "digit"},
					 {text: "E",type: "digit"},{text: "R",type: "digit"},
					 {text: "T",type: "digit"},{text: "Y",type: "digit"},
					 {text: "U",type: "digit"},{text: "I",type: "digit"},
					 {text: "O",type: "digit"},{text: "P",type: "digit"}],
					[{text: "A",type: "digit"},{text: "S",type: "digit"},
					 {text: "D",type: "digit"},{text: "F",type: "digit"},
					 {text: "G",type: "digit"},{text: "H",type: "digit"},
					 {text: "J",type: "digit"},{text: "K",type: "digit"},
					 {text: "L",type: "digit"}],
					[{text: "Z",type: "digit"},{text: "X",type: "digit"},
					 {text: "C",type: "digit"},{text: "V",type: "digit"},
					 {text: "B",type: "digit"},{text: "N",type: "digit"},
					 {text: "M",type: "digit"}],
					[{text: "回删",type: "delete"},],
				],
			};
		},

		methods: {
			// 处理键盘事件
			keyboardClick(event) {
				let text = event.currentTarget.innerText;
				let type = event.currentTarget.getAttribute("data-type");
				switch (type) {
					case "digit":
						this.password += text;
						this.fileForm.password = this.password;
						break;
					case "delete":
						this.password = this.password.substr(0, this.password.length - 1);
						this.fileForm.password = this.password
						break;
				}
				this.$refs.passwordInput.focus();
			},
			checkIn() {
				if (this.password == "") {
					this.$refs["passwordInput"].focus();
					return;
				}
				this.password = "";
				this.ifWritePopUp = false
			},
			//点击事件
			setFileClick() {
				this.clickCount += 1; // 每次点击增加计数器的值
				this.fileForm = {}
				if (this.clickCount === 5) {
					//检查是否要初始化设置文件打印消耗品配置的密码
					queryInitializeFile().then((res) => {
						if (res && res.code === 200) {
							this.clickCount = 0
							this.ifInitialize = res.data
							//true初始化设置文件打印消耗品配置的密码
							if (this.ifInitialize === true) {
								this.dialogSetFile = true
								this.password = ""
								this.ifWritePopUp = true
							}
						} else {
							this.$message.error(res.msg);
						}
					})
				}
			},
			//提交按钮
			submitForm() {
				if (!this.fileForm.password) {
					this.$message.warning('请输入密码');
					return;
				}
				// 密码正则表达式
				const passwordRegex = /^(?=.*[a-zA-Z])(?=.*\d)[a-zA-Z\d]{6,8}$/;
				if (!passwordRegex.test(this.fileForm.password)) {
					this.$message.warning('密码由数字和英文字母组成,且长度为6~8位');
					return;
				}
				//初始化设置文件打印消耗品配置密码
				initPassword(this.fileForm.password).then((res) => {
					if (res && res.code == 200) {
						this.clickCount = 0
						this.$message.success(res.msg);
						this.dialogSetFile = false
					} else {
						this.$message.error(res.msg);
					}
				});
			},
			//密码清空重置
			resetForm() {
				this.password = ''
				this.fileForm = {}
			},
		},
	};
</script>
<style lang="less" scoped>
	.login {
		padding-top: 80px;
	}
	.screen-sign-mid {
	  position: relative;
	  width: 100%;
	  height: 80px;
	  padding: 3px;
	  box-sizing: border-box;
	  background-color: #eee;
	  color: #34592d;
	}
	.screen-sign-mid .screen-sign-mid-inner {
	  width: 100%;
	  height: 100%;
	  position: relative;
	  box-sizing: border-box;
	}
	.self-el-input {
	  display: inline-block;
	  width: 78%;
	  height: 80%;
	  padding: 0 100px 0 15px;
	  font-size: 26px;
	  color: #000;
	  border: 2px solid #35b9ff;
	  border-radius: 10px;
	  -webkit-appearance: none;
	  background-color: #eee;
	  background-image: none;
	  -webkit-box-sizing: border-box;
	  box-sizing: border-box;
	  -webkit-transition: border-color .2s cubic-bezier(.645, .045, .355, 1);
	  transition: border-color .2s cubic-bezier(.645, .045, .355, 1);
	  outline: 0;
	}
	.self-el-button {
	  display: inline-block;
	  position: absolute;
	  top: 2px;
	  right: 2px;
	  width: 100px;
	  height: 56px;
	  margin: 0;
	  font-size: 22px;
	  border-radius: 10px;
	  border: 2px solid #35b9ff;
	  color: #fff;
	  background-color: #35b9ff;
	}
	 
	.keyboard-wrap {
	  width: 100%;
	  box-sizing: border-box;
	}
	 
	.keyboard-wrap .key-group-item {
	  width: 100%;
	  height: auto;
	  text-align: center;
	}
	 
	.key-group-item .key-item {
	  display: inline-block;
	  position: relative;
	  width: 50px;
	  height: 50px;
	  line-height: 50px;
	  margin: 0 2px 8px 2px;
	  color: #000;
	  font-size: 20px;
	  box-sizing: border-box;
	  -webkit-border-radius: 3px;
	  -moz-border-radius: 3px;
	  border-radius: 15px;
	  background-color: #dedede;
	  -webkit-user-select: none;
	  -moz-user-select: none;
	  -ms-user-select: none;
	  user-select: none;
	  cursor: pointer;
	}
</style>

代码详解 

1、键盘界面是根据keyList数组中定义的内容动态生成的。

  • 我在外层使用了v-show="ifWritePopUp"来控制键盘界面的显示与隐藏。
  • 通过v-for="(keyItem, index) in keyList" :key="index"遍历keyList数组,生成多个key-group-item,每个key-group-item代表一行键位。
  • 在每个key-group-item内部,再次通过v-for="(item, index) in keyItem" :key="index"遍历keyItem数组,生成具体的按键元素。
  • 每个按键元素使用:style属性来动态设置样式,根据item.type的值来确定是否为字母键位,从而动态设置宽度。
  • 通过:data-type="item.type" @click.stop="keyboardClick"将按键的类型和点击事件绑定到对应的DOM元素上。

 

上图所示方法,主要用于处理用户在虚拟键盘上的点击操作,动态更新密码输入框中的内容,并保持输入焦点的流畅切换

  • 当用户点击键盘上的按键时,触发keyboardClick方法,同时将事件对象event作为参数传入
  • 通过event.currentTarget获取被点击的按键元素,然后分别获取该按键的文本内容和数据类型;
  • 根据被点击的按键的数据类型,判断是字母键还是删除键,并进行相应的逻辑处理:
    • 若是字母键,则将该字母添加到密码输入框中,并更新fileForm.password的值;
    • 若是删除键,则从密码输入框中删除最后一个字符,并更新fileForm.password的值
  • 最后,调用this.$refs.passwordInput.focus()将焦点重新定位到密码输入框,以便继续执行输入或删除操作。

        我在这边设置了CSS样式属性display: none;可以使元素不显示在页面上(即隐藏)。这意味着该元素将不会占据任何空间,并且无法通过直接的交互方式与用户进行互动。

  @click.stop是Vue中阻止事件冒泡的指令(防止该事件继续向上传播,避免重复执行相同的事件处理函数)。它可以通过在事件处理函数中使用event.stopPropagation()方法来停止事件向父级元素传播。

        简单来说,当用户在元素上点击鼠标时,会触发该元素的点击事件,并向父级元素依次传播。如果在某个父级元素上绑定了相同类型的事件处理函数,则该函数也会被调用。


数字+英文字母键盘效果图展示

        未设置style="display: none;",隐藏输入框和确认按钮的效果图     

 

 


OVER!!! 

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

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

相关文章

数据库原理: 笛卡儿积

笛卡儿积&#xff08;Cartesian Product&#xff09;是集合论中的一个概念&#xff0c;也在数据库中的查询操作中经常使用。笛卡儿积是指两个集合&#xff08;或更多集合&#xff09;之间所有可能的组合。如果有两个集合A和B&#xff0c;它们的笛卡儿积记作A B&#xff0c;表示…

DevExpress WinForms Pivot Grid组件,一个类似Excel的数据透视表控件(一)

界面控件DevExpress WinForms的Pivot Grid组件是一个类似Excel的数据透视表控件&#xff0c;用于多维(OLAP)数据分析和跨选项卡报表。众多的布局自定义选项使您可以完全控制其UI&#xff0c;无与伦比的以用户为中心的功能使其易于部署。 DevExpress WinForms有180组件和UI库&a…

MongoDB知识总结

这里写自定义目录标题 MongoDB基本介绍MongoDB基本操作数据库相关集合相关增删改查 MongoDB基本介绍 简单介绍 MongoDB是一个基于分布式文件存储的数据库。由C语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。 MongoDB是一个介于关系数据库和非关系数据库之间的产…

C#图像处理OpenCV开发指南(CVStar,07)——通用滤波(Filter2D)的实例代码

1 函数定义 void Filter2D (Mat src, Mat dst, int ddepth, InputArray kernel, Point anchor Point(-1,-1), double delta 0, int borderType BORDER_DEFAULT ) 1.1 原型 #include <opencv2/imgproc.hpp> Convolves an image wit…

nodejs+vue+微信小程序+python+PHP新闻发布系统的设计与实现-计算机毕业设计推荐

根据现实需要&#xff0c;此系统我们设计出一下功能&#xff0c;主要有以下功能模板。 &#xff08;1&#xff09;新闻发布系统前台&#xff1a;首页、时事新闻、公告资讯、个人中心。 &#xff08;2&#xff09;管理员功能&#xff1a;首页、个人中心、用户管理、新闻分类管理…

利用STM32内置Bootloader实现USB DFU固件升级

本文将介绍如何利用STM32内置的Bootloader来实现USB DFU&#xff08;Device Firmware Upgrade&#xff09;固件升级功能。首先&#xff0c;我们会介绍USB DFU的原理和工作流程。然后&#xff0c;我们将详细讲解如何配置STM32芯片以支持USB DFU&#xff0c;并提供相应的代码示例…

第3章:知识表示:概述、符号知识表示、向量知识表示

&#x1f497;&#x1f497;&#x1f497;欢迎来到我的博客&#xff0c;你将找到有关如何使用技术解决问题的文章&#xff0c;也会找到某个技术的学习路线。无论你是何种职业&#xff0c;我都希望我的博客对你有所帮助。最后不要忘记订阅我的博客以获取最新文章&#xff0c;也欢…

Cocos Creator加入图片没有被识别

原因&#xff0c;需要更换类型&#xff0c;选择下图中的类型

【华为数据之道学习笔记】3-1 基于数据特性的分类管理框架

华为根据数据特性及治理方法的不同对数据进行了分类定义&#xff1a;内部数据和外部数据、结构化数据和非结构化数据、元数据。其中&#xff0c;结构化数据又进一步划分为基础数据、主数据、事务数据、报告数据、观测数据和规则数据。 对上述数据分类的定义及特征描述。 分类维…

2022年第十一届数学建模国际赛小美赛B题序列的遗传过程解题全过程文档及程序

2022年第十一届数学建模国际赛小美赛 B题 序列的遗传过程 原题再现&#xff1a; 序列同源性是指DNA、RNA或蛋白质序列之间的生物同源性&#xff0c;根据生命进化史中的共同祖先定义[1]。DNA、RNA或蛋白质之间的同源性通常根据它们的核苷酸或氨基酸序列相似性来推断。显著的相…

AWS re:Invent 2023-亚马逊云科技全球年度技术盛会

一:会议地址 2023 re:Invent 全球大会主题演讲 - 亚马逊云科技从基础设施和人工智能/机器学习创新,到云计算领域的最新趋势与突破,倾听亚马逊云科技领导者谈论他们最关心的方面。https://webinar.amazoncloud.cn/reInvent2023/keynotes.html北京时间2023年12月1日00:30-02:…

解决mybatis-plus中,当属性为空的时候,update方法、updateById方法无法set null,直接忽略了

问题描述 当indexId set 22的时候是可以set的 我们发现sql语句也是正常的 表中数据也被更改了 但是当我们indexId为空的时候 sql语句中没有了set indexId这一属性。。 既然属性都没了&#xff0c;表是肯定没做修改的 问题解决 在实体类对应的字段上加注解TableField(strategy…

“城中村上建高楼”,开启一场数智化时代新修炼

“数字化也好&#xff0c;数智化也罢&#xff0c;你明明白白地告诉我&#xff0c;他们与信息化到底有什么区别&#xff1f;” “我在信息化方面已投入那么多&#xff0c;为什么又要投那么多钱搞数智化&#xff1f;” 中国软件网、海比研究院在《2024中国企业数智服务趋势洞察研…

Linux进程解析(冯诺依曼体系结构,操作系统,进程初步解析)

冯诺依曼体系结构&#xff1a; 我们常见的计算机&#xff0c;如笔记本。我们常见的计算机&#xff0c;服务器&#xff0c;大部分都遵守冯诺依曼体系。 截至目前&#xff0c;我们所认识的计算机&#xff0c;都是有一个个的硬件组件组成&#xff1a; 中央处理器(CPU)&am…

Stm32_串口的帧(不定长)数据接收

目录标题 前言1、串口中断接收固定帧头帧尾数据1.1、任务需求1.2、实现思路1.3、程序源码&#xff1a; 2、串口中断接收用定时器来判断帧结束3、串口中断接收数据空闲中断3.1、串口的空闲中断3.2、实现思路3.3、程序源码 4、串口的空闲中断DMA转运4.1、DMA简介4.2、DMA模式4.3、…

【从0配置JAVA项目相关环境2】node.js + 前端 从配置到运行

运行前端项目 写在最前面一、安装node.js二、运行前端项目1. 运行 npm install2. 运行 npm run serve报错Error: error:0308010C:digital envelope routines::unsupported方法1&#xff1a;设置 NODE_OPTIONS &#xff08;没用&#xff09;方法2&#xff1a;更改Node.js版本方法…

我把springboot项目从Java 8 升级 到了Java 17 的过程总结,愿为君提前踩坑!

项目从jdk8升级到jdk17&#xff0c;我不是为了追求java 17的新特性&#xff08;准确来说也还没有去了解有什么新特性&#xff09;&#xff0c;也不是为了准确与时俱进&#xff0c;永远走在java行列的最前端&#xff0c;纯粹因为项目需要&#xff0c;因为我们都知道&#xff0c;…

日志框架梳理(Log4j,Reload4j,JUL,JCL,SLF4J,Logback,Log4j2)

原文链接 日志框架发展历程 在了解日志框架时总会列出一系列框架&#xff1a;Log4j&#xff0c;Reload4j&#xff0c;JUL&#xff0c;JCL&#xff0c;SLF4J&#xff0c;Logback&#xff0c;Log4j2&#xff0c;这么多框架让人感到混乱&#xff0c;该怎么选取、该怎么用。接下来…

LV.12 D23 IIC控制器与MPU6050 学习笔记

一、Exynos_4412下的IIC控制器 ​ 4412有四个IIC&#xff0c;如果要使用需要配置四个寄存器 I2CCON&#xff1a;配置一些功能 I2CSTAT&#xff1a;控制一些功能、显示一些状态 I2CDS&#xff1a;发送和接收数据 I2CADD&#xff1a;当4412作为从机时需要一个地址&#xff…

亚马逊云科技Serverless视频内容摘要提取方案

概述 随着GenAI的普及&#xff0c;视频内容摘要生成成为一个备受关注的领域。通过将视频内容转化为文本&#xff0c;可以探索到更广泛的应用场景&#xff0c;其中包括&#xff1a; 视频搜索与索引&#xff1a;将视频内容转化为文本形式&#xff0c;可以方便地进行搜索和索引操作…