【uniapp】短信验证码输入框

news2024/11/19 20:31:43

需求是短信验证码需要格子输入框 如图

在这里插入图片描述

网上找了一个案例改吧改吧 直接上代码

结构

在这里插入图片描述


<template>
	<view class="verify-code">
		<!-- 输入框 -->
		<input id="input" :value="code" class="input" :focus="isFocus" :type="inputType" :maxlength="itemSize"
			@input="onInput" @focus="inputFocus" @blur="inputBlur" />

		<!-- 光标 -->
		<view id="cursor" v-if="cursorVisible && type !== 'middle'" class="cursor"
			:style="{ left: codeCursorLeft[code.length] + 'px', height: cursorHeight + 'px', backgroundColor: cursorColor }">
		</view>

		<!-- 输入框 --->
		<view id="input-ground" class="input-ground">
			<view v-for="(item, index) in itemSize" :key="index"
				:style="{ borderColor: code.length === index && cursorVisible ? boxActiveColor : boxNormalColor }"
				:class="['box', `box-${type + ''}`, `box::after`]">
				<view :style="{ borderColor: boxActiveColor }" class="middle-line"
					v-if="type === 'middle' && !code[index]"></view>

				<text class="code-text">{{ code[index] | codeFormat(isPassword) }}</text>
			</view>
		</view>
	</view>
</template>

<script>
	/**
	 * @description 输入验证码组件
	 * @property {string} type = [box|middle|bottom] - 显示类型 默认:box -eg:bottom
	 * @property {string} inputType = [text|number] - 输入框类型 默认:number -eg:number
	 * @property {number} size - 验证码输入框数量 默认:6 -eg:6
	 * @property {boolean} isFocus - 是否立即聚焦 默认:true
	 * @property {boolean} isPassword - 是否以密码形式显示 默认false -eg: false
	 * @property {string} cursorColor - 光标颜色 默认:#cccccc
	 * @property {string} boxNormalColor - 光标未聚焦到的框的颜色 默认:#cccccc
	 * @property {string} boxActiveColor - 光标聚焦到的框的颜色 默认:#000000
	 * @event {Function(data)} confirm - 输入完成回调函数
	 */
	import {
		getElementRect
	} from './util.js';
	export default {
		name: 'verify-code',
		props: {
			value: {
				type: String,
				default: () => ''
			},
			type: {
				type: String,
				default: () => 'box'
			},
			inputType: {
				type: String,
				default: () => 'number'
			},
			size: {
				type: Number,
				default: () => 6
			},
			isFocus: {
				type: Boolean,
				default: () => true
			},
			isPassword: {
				type: Boolean,
				default: () => false
			},
			cursorColor: {
				type: String,
				default: () => '#cccccc'
			},
			boxNormalColor: {
				type: String,
				default: () => '#cccccc'
			},
			boxActiveColor: {
				type: String,
				default: () => '#000000'
			}
		},
		model: {
			prop: 'value',
			event: 'input'
		},
		data() {
			return {
				cursorVisible: false,
				cursorHeight: 35,
				code: '', // 输入的验证码
				codeCursorLeft: [], // 向左移动的距离数组,
				itemSize: 6,
				getElement: getElementRect(this),
				isPatch: false
			};
		},
		created() {
			this.cursorVisible = this.isFocus;
			this.validatorSize();
		},
		mounted() {
			this.init();
		},
		methods: {
			/**
			 * 设置验证码框数量
			 */
			validatorSize() {
				if (this.size > 0) {
					this.itemSize = Math.floor(this.size);
				} else {
					throw "methods of 'size' is integer";
				}
			},
			/**
			 * @description 初始化
			 */
			init() {
				this.getCodeCursorLeft();
				this.setCursorHeight();
			},
			/**
			 * @description 计算光标的高度
			 */
			setCursorHeight() {
				this.getElement('.box', 'single', boxElm => {
					this.cursorHeight = boxElm.height * 0.6;
				});
			},
			/**
			 * @description 获取光标在每一个box的left位置
			 */
			getCodeCursorLeft() {
				// 获取父级框的位置信息
				this.getElement('#input-ground', 'single', parentElm => {
					const parentLeft = parentElm.left;
					// 获取各个box信息
					this.getElement('.box', 'array', elms => {
						this.codeCursorLeft = [];
						elms.forEach(elm => {
							this.codeCursorLeft.push(elm.left - parentLeft + elm.width / 2);
						});
					});
				});
			},

			// 输入框输入变化的回调
			onInput(e) {
				let {
					value,
					keyCode
				} = e.detail;
				this.cursorVisible = value.length < this.itemSize;
				this.code = value;
				this.$emit('input', value);
				this.inputSuccess(value);
			},

			// 输入完成回调
			inputSuccess(value) {
				if (value.length === this.itemSize && !this.isPatch) {
					this.$emit('confirm', value);
				} else {
					this.isPatch = false;
				}
			},
			// 输入聚焦
			inputFocus() {
				this.cursorVisible = this.code.length < this.itemSize;
			},
			// 输入失去焦点
			inputBlur() {
				this.cursorVisible = false;
			}
		},
		watch: {
			value(val) {
				if (val !== this.code) {
					this.code = val;
				}
			}
		},
		filters: {
			codeFormat(val, isPassword) {
				return val ? (isPassword ? '*' : val) : '';
			}
		}
	};
</script>
<style scoped>
	.verify-code {
		position: relative;
		width: 100%;
		box-sizing: border-box;
	}

	.verify-code .input {
		height: 100%;
		width: 200%;
		position: absolute;
		left: -100%;
		z-index: 1;
		color: transparent;
		caret-color: transparent;
		background-color: rgba(0, 0, 0, 0);
	}

	.verify-code .cursor {
		position: absolute;
		top: 50%;
		transform: translateY(-50%);
		display: inline-block;
		width: 2px;
		animation-name: cursor;
		animation-duration: 0.8s;
		animation-iteration-count: infinite;
	}

	.verify-code .input-ground {
		display: flex;
		justify-content: space-between;
		align-items: center;
		width: 100%;
		box-sizing: border-box;
	}

	.verify-code .input-ground .box {
		position: relative;
		display: inline-block;
		width: 100rpx;
		height: 140rpx;
	}

	.verify-code .input-ground .box-bottom {
		border-bottom-width: 2px;
		border-bottom-style: solid;
	}

	.verify-code .input-ground .box-box {
		border-width: 2px;
		border-style: solid;
	}

	.verify-code .input-ground .box-middle {
		border: none;
	}

	.input-ground .box .middle-line {
		position: absolute;
		top: 50%;
		left: 50%;
		width: 50%;
		transform: translate(-50%, -50%);
		border-bottom-width: 2px;
		border-bottom-style: solid;
	}

	.input-ground .box .code-text {
		position: absolute;
		top: 50%;
		left: 50%;
		font-size: 80rpx;
		transform: translate(-50%, -50%);
	}

	@keyframes cursor {
		0% {
			opacity: 1;
		}

		100% {
			opacity: 0;
		}
	}
</style>

util.js

/**
 * @description 获取元素节点 - 大小等信息
 * @param {string} elm - 节点的id、class 相当于 document.querySelect的参数 -eg: #id
 * @param {string} type = [single|array] - 单个元素获取多个元素 默认是单个元素
 * @param {Function} callback - 回调函数
 * @param {object} that - 上下文环境 vue2:this ,vue3: getCurrentInstance();
 */
export const getElementRect = (that) => (elm, type = 'single', callback) => {
	// #ifndef H5
	uni
		.createSelectorQuery()
		.in(that)[type === 'array' ? 'selectAll' : 'select'](elm)
		.boundingClientRect()
		.exec(data => {
			callback(data[0]);
		});
	// #endif

	// #ifdef H5
	let elmArr = [];
	const result = [];
	if (type === 'array') {
		elmArr = document.querySelectorAll(elm);
	} else {
		elmArr.push(document.querySelector(elm));
	}

	for (let elm of elmArr) {
		result.push(elm.getBoundingClientRect());
	}
	console.log('result', result)
	callback(type === 'array' ? result : result[0]);
	// #endif
}

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

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

相关文章

Ubuntu安装Jitsi Meet详细教程

文章目录 Ubutu系统安装启用root账户切换Ubuntu源设置DNS 主机名和域名配置安装open JDK安装Nginx安装 Jitsi Meetjitsi本地测试使用一个奇怪的BUG Jist服务管理 Ubutu系统安装 官方推荐用Ubuntu&#xff0c;网上很多教程也都是基于Ubuntu的&#xff0c;所以选择这个系统。 其…

【Python Numpy】Ndarray属性

文章目录 前言一、NumPy数组的常用属性1.1 常用属性1.2 示例代码 总结 前言 NumPy&#xff08;Numerical Python&#xff09;是Python中用于科学计算的一个重要库&#xff0c;它提供了一个强大的多维数组对象&#xff08;ndarray&#xff09;以及一系列用于处理这些数组的函数…

从0到1:CTFer成长之路——死亡 Ping 命令

死亡 ping 命令 绕过探测 手动尝试 慢 脚本生成转义后的字符&#xff0c;后面拼接命令 import urllib.parsewith open(r"C:\Users\LEGION\Desktop\RCE.txt", "w", encoding"utf-8") as f:for i in range(0, 255):encoded_str urllib.parse…

短篇小说 《镜花水月》

最近脑中不知道为什么&#xff0c;一直构想着这样一个故事&#xff0c;心血来潮&#xff0c;还是想把它直接付诸实践。如果大家有些兴趣可以读一读&#xff0c;欢迎评论留言&#xff0c;发表自己的看法&#xff0c;大家也可以给一些建议或者自己设计一些比较好的情节或者点&…

leetcode第80题:删除有序数组中的重复项 II

题目描述 给你一个有序数组 nums &#xff0c;请你 原地 删除重复出现的元素&#xff0c;使得出现次数超过两次的元素只出现两次 &#xff0c;返回删除后数组的新长度。 不要使用额外的数组空间&#xff0c;你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。 …

一种实用的边的存储结构--链式前向星

文章目录 前言前向星定义存储结构优缺点 链式前向星边的定义边的插入边的查找运行示例 总结 前言 我们对于图的存储方式常用的有邻接矩阵&#xff08;适用于稠密图&#xff09;&#xff0c;对于边的查询效率较低&#xff0c;也有邻接表&#xff0c;对于边的查询效率高&#xf…

警报:Citrix和VMware漏洞的PoC利用代码已发布

导语 近日&#xff0c;虚拟化服务提供商VMware向客户发出警报&#xff0c;称其Aria Operations for Logs中的一个已修补安全漏洞的PoC利用代码已经发布。这个高危漏洞&#xff08;CVE-2023-34051&#xff09;是一种绕过身份验证的情况&#xff0c;可能导致远程代码执行。本文将…

【备考网络工程师】如何备考2023年网络工程师之上午常见考点篇(上)

目录 写在前面涉及知识点一、香农定理与奈奎斯特定理问题1.1 香农定理1.2 尼奎斯特定理 二、E1与T1问题三、数据传输延迟问题3.1 对于电缆3.2 对于卫星 四、数字化技术PCM计算问题五、CSMA/CD以太帧最小帧长计算问题六、CSMA/CD考点汇总七、CSMA/CA考点汇总八、各协议注意事项总…

初步认识 Web Components 并实现一个按钮

目录 1.Web Components 基本概念 1.1 三个场景 1.2 是什么 2.使用 Custom Elements 实现一个按钮 2.1 概念介绍 2.1.1 Shadow DOM 2.1.2 Element.attachShadow() 2.1.3 在组件中 使用 Shadow DOM 基本步骤 2.1.4 attributeChangedCallback 2.1.5 get observedAttribu…

绝对路径与相对路径

目录 一、绝对路径 二、相对路径 三、举例 一、绝对路径 绝对路径是指从根目录开始的完整路径&#xff0c;包括所有父目录的路径&#xff0c;直到目标文件或者目录 所在的位置。 全文件名全路径文件名绝对路经完整的路径 例如:在windows系统中&#xff0c;绝对路径通常以…

nuxt脚手架

nuxt(vue)和next(react)都是服务端渲染的 安装 - NuxtJS | Nuxt.js 中文网 首先要安装 create-nuxt-app: npm install create-nuxt-app -g 然后&#xff1a;npx create-nuxt-app master 建议在cmd中操作&#xff0c;可以单选和多选 然后就各种单选和多选&#xff0c;多选按…

实用篇-服务拆分及远程调用

一、服务拆分 服务拆分(也叫项目拆分) 注意事项&#xff1a; 不同的微服务&#xff0c;不要重复开发相同的业务要求微服务之间数据独立&#xff0c;不要访问其他微服务的数据库微服务可用将自己的业务暴漏为接口&#xff0c;供其他服务调用 1. Cloud-Demo拆分 首先有一个已…

项目管理之如何有效定义项目目标

项目目标管理是项目管理中非常重要的一个环节&#xff0c;它可以帮助项目团队明确目标&#xff0c;制定合理可行的计划&#xff0c;确保项目顺利实施并取得成功。在定义项目目标时&#xff0c;需要遵循SMART原则&#xff0c;确保目标具体、明确、可衡量、可实现、相关且有时间和…

【Reticulate Micro】申请1000万美元纳斯达克IPO上市

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 猛兽财经获悉&#xff0c;总部位于美国的【Reticulate Micro】近期已向美国证券交易委员会&#xff08;SEC&#xff09;提交招股书&#xff0c;申请在纳斯达克IPO上市&#xff0c;股票代码为(RMIC) &#xff0c;Reticulate…

TensorFlow学习:使用官方模型和自己的训练数据进行图片分类

前言 教程来源&#xff1a;清华大佬重讲机器视觉&#xff01;TensorFlowOpencv&#xff1a;深度学习机器视觉图像处理实战教程&#xff0c;物体检测/缺陷检测/图像识别 注&#xff1a; 这个教程与官网教程有些区别&#xff0c;教程里的api比较旧&#xff0c;核心思想是没有变…

C++——类和对象(了解面向过程和面向对象、初步认识类和对象、类大小的计算、this指针)

类和对象 文章目录 类和对象1. 面向过程和面向对象1.1 面向过程1.2 面向对象 2. 类和对象2.1 什么是类2.2 类的定义2.2.1 声明和定义类中函数的两种方法2.2.2 声明成员变量的小细节 2.3 访问限定符2.3.1 访问限定符的作用范围2.3.2 class类和struct类的默认访问权限 2.4 类的实…

手部关键点检测5:C++实现手部关键点检测(手部姿势估计)含源码 可实时检测

手部关键点检测5&#xff1a;C实现手部关键点检测(手部姿势估计)含源码 可实时检测 目录 手部关键点检测4&#xff1a;C实现手部关键点检测(手部姿势估计)含源码 可实时检测 1.项目介绍 2.手部关键点检测(手部姿势估计)方法 (1)Top-Down(自上而下)方法 (2)Bottom-Up(自下…

mac vscode 使用 clangd

C 的智能提示 IntelliSense 非常不准&#xff0c;我们可以使用 clangd clangd 缺点就是配置繁琐&#xff0c;优点就是跳转和提示代码精准 开启 clangd 之后会提示你关闭 IntelliSense 1、安装插件 clangd 搜索第一个下载多的就是 2、配置 clangd 可执行程序路径 clangd 插…

【虹科干货】谈谈Redis Enterprise的实时搜索

我们都知道&#xff0c;用户在使用应用程序时候&#xff0c;对于速度有着越来越高的要求&#xff0c;真可谓是“一秒也等不及”。而开发团队又该怎样来满足这种对于实时性的期望呢&#xff1f; 文章速览&#xff1a; Redis Enterprise实时搜索的应用场景利用索引为开发人员带…

特殊类设计[下] --- 单例模式

文章目录 5.只能创建一个对象的类5.1设计模式[2.5 万字详解&#xff1a;23 种设计模式](https://zhuanlan.zhihu.com/p/433152245)5.2单例模式1.饿汉模式1.懒汉模式 6.饿汉模式7.懒汉模式7.1饿汉模式优缺点:7.2懒汉模式1.线程安全问题2.单例对象的析构问题 8.整体代码9.C11后可…