UniApp手机滑块验证组件代码生成器

news2024/10/1 23:47:15

DIY可视化实现UniApp手机滑块验证组件,支持自定义背景图片、成功提示、错误提示、划动提示等。

手机滑块验证组件是一种广泛应用于手机应用、网页等场景的用户验证机制,其主要目的是通过用户的滑动操作来验证用户的真实性和操作意图,从而增强系统的安全性。以下是对手机滑块验证组件的详细介绍:

一、工作原理

滑块验证组件的工作原理基于人机交互的思想,通过要求用户在屏幕上滑动指定的滑块到特定位置来完成验证。这一过程结合了用户的视觉和运动能力,使得验证过程更加难以被自动化程序绕过。

二、组成元素

手机滑块验证组件通常包含以下几个关键元素:

  1. 滑块:用户需要操作的对象,通常是一个可拖动的图标或图形。
  2. 背景图:滑块需要与之匹配或对齐的图像,背景图上通常包含有特定的图案或元素,用于引导用户找到正确的滑动位置。
  3. 指示信息:提示用户如何操作的文字或图形信息,如“拖动滑块完成验证”。
  4. 验证逻辑:后台的验证算法,用于判断用户的滑动操作是否符合预期,包括滑块的位置、滑动轨迹等。

三、操作流程

  1. 显示验证页面:当用户需要进行验证时,系统会生成一张包含滑块和背景图的验证码图片,并显示在用户的手机上。
  2. 用户操作:用户用手指按住滑块,并沿着屏幕指示的方向拖动,直到滑块到达背景图的指定位置。
  3. 验证结果:系统会根据用户的滑动操作进行验证,如果验证通过,用户将获得验证成功的反馈;如果验证失败,用户需要重新进行验证。

四、优势与应用

手机滑块验证组件具有以下优势:

  1. 提高安全性:通过结合用户的视觉和运动能力进行验证,增加了自动化程序绕过的难度。
  2. 提升用户体验:相比传统的验证码输入方式,滑块验证更加简单直观,用户只需进行简单的滑动操作即可完成验证。
  3. 适用范围广:可以灵活应用于各种手机应用、网页等场景,满足不同的验证需求。

手机滑块验证组件广泛应用于各类网站和移动应用中,如用户注册、登录、重置密码等场景。它通过简单的滑动操作,有效地保护了用户的账户安全,并提升了用户体验。

五、技术实现

手机滑块验证组件的实现通常涉及图像处理、机器学习等技术。系统需要能够生成复杂的背景图、随机放置滑块位置、捕捉用户的滑动轨迹等。同时,还需要具备高效的验证算法,以快速准确地判断用户的滑动操作是否符合预期。

综上所述,手机滑块验证组件是一种简单有效且广泛应用的用户验证机制,它通过结合用户的视觉和运动能力进行验证,提高了系统的安全性和用户体验。

六、UniApp组件库实现

<template>
	<view class="diy-verify" v-if="initShow" :class="isModal?'diy-verify-modal':''" :id="elid"  @touchmove.stop.prevent="stopMoveHandle" :style="verifyWidthStyle">
		<view class="diy-verify-close" @tap="close" v-if="isModal">
			<u-icon :size="50" color="#fff" name="close"></u-icon>
		</view>
		<view class="diy-verify-wrap"  v-if="isShow">
			<view class="diy-verify-box">
				<image class="diy-verify-img" v-if="verifyImg" :src="verifyImg" mode="scaleToFill"></image>
				<!-- 右侧用来验证的滑块 -->
				<view class="diy-verify-block-verify" :style="blockVerifyStyle"></view>
				<!-- 被css操控的滑块 -->
				<view class="diy-verify-block-move" :style="blockMoveStyle"></view>
				
				<view class="diy-verify-tips" v-if="!showBottomVerify">
					<text class="diy-verify-tips-text" :style="blockTipsStyle">{{ tips }}</text>
				</view>
				<!-- 手指触摸的滑块 -->
				<view class="diy-verify-block-touch" :style="blockTouchStyle" @touchstart="touchstartHandle"
					@touchmove="touchmoveHandle" @touchend="touchendHandle">
				</view>
				<view @tap="initVerify()" class="diy-verify-refresh">
					<u-icon :size="50" :color="refreshColor" name="reload"></u-icon>
				</view>
			</view>
			<view class="diy-verify-verify" v-if="showBottomVerify"  :style="verifyBottomStyle">
				<view   :class="(isSuccess?'diy-verify-success-text':'diy-verify-text')">{{tips}}</view>
				<!-- 被css操控的滑块 -->
				<view class="diy-verify-verify-move" :style="verifyMoveStyle">
					<u-icon :size="bottomSize-10" :name="isSuccess?'checkbox-mark':'arrow-right-double'"></u-icon>
				</view>
				<!-- 手指触摸的滑块 -->
				<view class="diy-verify-verify-touch" :style="verifyTouchStyle" @touchstart="touchstartHandle" 	@touchmove="touchmoveHandle" @touchend="touchendHandle">
				</view>
			</view>
		</view>
	</view>
</template>

<script>
	export default {
		name: 'zmmVerifyVerify',
		emits: ["update:modelValue",'close',"change"],
		props: {
			// 通过双向绑定控制组件的弹出与收起
			modelValue: {
				type: Boolean,
				default: false
			},
			//是否弹窗验证
			isModal:{
				type:Boolean,
				default: false
			},
			//提醒
			tip: {
				type: String,
				default: '请将左侧透明滑块拖进白色框内'
			},
			successTip: {
			     type: String,
			     default: "验证通过"
			},
			failTip:{
			  type: String,
			  default: "验证失败"
			},
			//滑块大小
			verifySize: {
				type: Number,
				default: 50
			},
			//滑块颜色
			verifyColor: {
				type: String,
				default: 'rgba(0,0,0,0.4)'
			},
			//图片验证高度
			verifyHeight:{
				type: Number,
				default: 170
			},
			// 图片
			verifyImg: {
				type: String,
				default: ''
			},
			//刷新颜色
			refreshColor: {
				type: String,
				default: '#ffffff'
			},
			//校验正负差值区间像素
			between: {
				type: Number,
				default: 10
			},
			//如果不显示底部滑动条时提示字段颜色
			tipColor:{
			  type: String,
			  default: '#ffff00'
			},
			// 是否显示底部滑动条
			showBottomVerify: {
				type: Boolean,
				default: false
			},
			//底部滑块大小
			bottomSize: {
				type: Number,
				default: 40
			},
			bottomBarColor: {
				type: String,
				default: '#eee'
			},
			bottomSuccessColor: {
				type: String,
				default: '#19be6b'
			},
			//底部滑块颜色
			bottomBgColor: {
			      type: String,
			      default: '#ffffff'
			},
			bottomColor: {
			  type: String,
			  default: '#bbbbbb'
			},
			bottomBorderColor: {
			  type: String,
			  default: '#bbbbbb'
			},
		},
		data() {
			return {
				elid: this.$u.guid(),
				verifyWidth:280,
				initShow:!this.isModal,
				tips:this.tip,
				startPageX: 0, //开始距离
				moveLeft: 0, //滑动距离
				isSuccess: false, //是否成功
				autoLeft: 80, //验证滑块随机的像素
				autoTop: 80, //验证滑块随机的top像素
				isShow: false
			};
		}, 
        watch: {
			verifyImg: {
			  immediate: true,
			  handler(){
				  this.init()
			  }
			}
		},
		computed: {
			verifyWidthStyle(){
				return `--diy-verify-width:${this.verifyWidth}px;--diy-verify-height:${this.verifyHeight}px`
			},
			blockVerifyStyle() {
				return `top:${this.autoTop}px;left:${this.autoLeft}px;height:${this.verifySize}px;width:${this.verifySize}px;background-color:${this.verifyColor};`
			},
			blockMoveStyle() {
				let moveLeft = this.isSuccess?this.autoLeft:this.moveLeft;
				return `top:${this.autoTop}px;left:${moveLeft}px;height:${this.verifySize}px;width:${this.verifySize}px;background-color: ${this.verifyColor};`
			},
			blockTipsStyle(){
				return `color:${this.tipColor}`
			},
			blockTouchStyle() {
				return `top:${this.autoTop}px;height:${this.verifySize}px;width:${this.verifySize}px;`
			},
			verifyMoveStyle() {
				let moveLeft = this.isSuccess?this.autoLeft:this.moveLeft;
				return `border:1px solid ${this.bottomBorderColor};left:${moveLeft}px;height:${this.bottomSize}px;width:${this.bottomSize}px;color:${this.bottomColor};background-color: ${this.bottomBgColor};`
			},
			verifyTouchStyle() {
				return `height:${this.bottomSize}px;width:${this.bottomSize}px;`
			},
			verifyBottomStyle() {
				return `font-size:${this.bottomSize-26}px;line-height:${this.bottomSize}px;height:${this.bottomSize}px;background-color:${this.isSuccess?this.bottomSuccessColor:this.bottomBarColor}`
			}
		},
		mounted() {
			this.init()
		},
		methods: {
			// 初始化
			init() {
				if(this.initShow){
					this.$nextTick(()=>{
						this.$uGetRect('#' + this.elid).then((res) => {
							this.verifyWidth = this.isModal?res.width-20:res.width;
							this.initVerify()
						});
					})
				}
			},
			initVerify(){
				this.isShow = true
				this.moveLeft = 0;
				this.isSuccess = false;
				this.autoTop = this.randPostion(0, this.verifyHeight - this.verifySize);
				this.autoLeft = this.randPostion(this.verifySize + 20, this.verifyWidth - this.verifySize);
			},
			show(){
				this.initShow = true;
				this.init();
			},
			close(){
				if(this.isModal){
					this.initShow = false;
					this.$emit("close");
				}
			},
			// 拦截其他触摸事件防止nvue下input等元素层级问题
			stopMoveHandle(e) {
				if (e.preventDefault) {
					// 阻止页面滚动
					e.preventDefault()
				}
			},
			// 随机数
			randPostion(min, max) {
				//返回包括最大/小值
				return Math.floor(Math.random() * (max - min + 1)) + min;
			},
			//按下
			touchstartHandle(e) {
				if (this.isSuccess) {
					return;
				}
				this.startPageX = e.changedTouches[0].pageX;
			},
			// 滑动
			touchmoveHandle(e) {
				// 滑动分两个块来操作不然会有数据抖动
				if (this.isSuccess) {
					return;
				}
				var left = e.changedTouches[0].pageX - this.startPageX; //补偿起始位置
				this.moveLeft = left;
			},
			// 滑动离开(最终)
			touchendHandle(e) {
				var endLeft = e.changedTouches[0].pageX;
				var verifyLeft = this.autoLeft + this.startPageX; //补偿起始位置
				var chazhi = verifyLeft - endLeft; //最终差值
				// 判断是否在正负差值区间
				if (chazhi >= 0 - this.between && chazhi <= this.between) {
					this.isSuccess = true;
					// 通过会执行成功和关闭
					this.tips = this.successTip
					this.$emit("update:modelValue", true);
					this.$emit("change", true);
					uni.showToast({
						icon:'none',
						title:this.successTip?this.successTip:'验证通过'
					})
					this.close()
				} else {
					this.tips = this.failTip?this.failTip:'验证失败';
					setTimeout(()=>{
						this.tips = this.tip;
					})
					// 失败会执行失败并重新初始化
					this.show();
					uni.showToast({
						title: this.failTip?this.failTip:'验证失败',
						icon: 'none'
					});
					this.$emit("update:modelValue", false);
					this.$emit("change", false);
				}
			}
		}
	};
</script>

<style lang="scss" scoped>
	.diy-verify {
		--diy-verify-width:280px;
		--diy-verify-height:170px;
		--textColor:#4d4d4d;
		width: 100%;
		display: flex;
		flex-direction: row;
		align-items: center;
		justify-content: center;
		&.diy-verify-modal{
			position: fixed;
			top:0px;
			left:0px;
			width: 100%;
			height: 100%;
			background: rgba(0, 0, 0, 0.6);
			z-index: 99999999;
			transition: all 0.3s ease-in-out 0s;
			
			.diy-verify-close{
				position: absolute;
				top:10px;
				right: 10px;
			}
			.diy-verify-wrap {
				opacity: 1;
				transition-duration: 0.3s;
				-ms-transform: scale(1);
				transform: scale(1);
				overflow-x: hidden;
				overflow-y: auto;
				pointer-events: auto;
			}
		}

		.diy-verify-wrap {
			display: flex;
			flex-direction: column;
			position: relative;
			margin: 0 auto;
			width: var(--diy-verify-width); 
			background-color: #ffffff;
 
			.diy-verify-tips {
				position: absolute;
				left:0;
				bottom: 0;
				width: 100%;
				background: rgba(0, 0, 0, .6);
				font-size: 12px;
				line-height: 20px;
				text-align: center;

				.diy-verify-tips-text {
					color: #ff0;
				}
			}
			.diy-verify-refresh{
				position: absolute;
				right: 10px;
				top: 10px;
			}

			.diy-verify-text{
				position: absolute;
				left: 0;
				top: 0;
				width: 100%;
				height: 100%;
				color: #FFFFFF;
				text-align: center;
				background: -webkit-gradient(linear,left top,right top,color-stop(0,var(--textColor)),color-stop(.4,var(--textColor)),color-stop(.5,#fff),color-stop(.6,var(--textColor)),color-stop(1,var(--textColor)));
				animation: slidetounlock 3s infinite;
				-webkit-background-clip: text;
				-webkit-text-fill-color: transparent;
			}
			.diy-verify-success-text{
				position: absolute;
				left: 0;
				top: 0;
				width: 100%;
				text-align: center;
				color: #FFFFFF;
			}

			@keyframes slidetounlock{
				0% {
					background-position: -200rpx 0;
				}
				100% {
					background-position: 200rpx 0;
				}
			}
			.diy-verify-box {
				position: relative;
				width: var(--diy-verify-width);
				height: var(--diy-verify-height);
				overflow: hidden;

				.diy-verify-img {
					width: var(--diy-verify-width);
					height: var(--diy-verify-height);
					border-radius: 0px;
				}

				.diy-verify-block-verify,
				.diy-verify-block-move,
				.diy-verify-block-touch {
					position: absolute;
					left: 0px;
					top: 0;
					border-radius: 0px;
				}

				.diy-verify-block-verify {
					border:1px solid #fff;
				}
			}

			.diy-verify-verify {
				height:40px;
				width: var(--diy-verify-width);
				background-color: rgba(0,0,0,0.07);
				position: relative;
				overflow: hidden;
				.diy-verify-verify-move{
					display: flex;
					align-items: center;
					justify-content: center;
				}
				.diy-verify-verify-move,
				.diy-verify-verify-touch {
					border-radius: 0px;
				}
  
				.diy-verify-verify-move,.diy-verify-verify-touch {
					position: absolute;
					left: 0px;
					top: 0px;
				}
			}
		}
	}
</style>

七、组件使用

<template>
	<view class="container container23285">
		<view class="diygw-col-24">
			<diy-verify v-model="verify" successBarColor="#ff3d0c"></diy-verify>
		</view>
		<view class="diygw-col-24">
			<diy-verifyimg class="diygw-col-24" v-model="verifyimg" :verifySize="50" verifyImg="/static/pic1.jpg" :showBottomVerify="true"></diy-verifyimg>
		</view>
		<view class="clearfix"></view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				//用户全局信息
				userInfo: {},
				//页面传参
				globalOption: {},
				//自定义全局变量
				globalData: { logintype: '0', agree: '0' },
				verify: false,
				verifyimg: false
			};
		},
		onShow() {
			this.setCurrentPage(this);
		},
		onLoad(option) {
			this.setCurrentPage(this);
			if (option) {
				this.setData({
					globalOption: this.getOption(option)
				});
			}

			this.init();
		},
		methods: {
			async init() {}
		}
	};
</script>

<style lang="scss" scoped>
	.container23285 {
	}
</style>

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

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

相关文章

双目视觉标定的一般方法

1 双目立体相机 双目立体相机是由两个单目相机根据 特定的参数组合而成&#xff0c;工作时可将左右两相机捕捉到的二维图像信息转换到三维立体空间 中&#xff0c;进而通过系列转换变为所需要的三维空间坐标信息。 2 一般过程 双目立体相机标定步骤一般有以下几个步骤&#…

RabbitMQ应用场景及特性

RabbitMQ是一款开源的消息队列中间件&#xff0c;拥有非常好用的管理控制面板&#xff0c;类似使用navicat一样&#xff0c;简便的操纵数据库。 应用场景 一、流量削峰 在一些并发量较高的场景下&#xff0c;比如秒杀活动&#xff0c;抢票等&#xff0c;同一时间访问量急剧增…

C#数据类型 全局变量 类型转换方法(汇总)

1、C#和S7-1200PLC S7.NET通信 C#和S7-1200PLC S7.NET通信-CSDN博客文章浏览阅读98次。一步步建立一个C#项目(连续读取S7-1200PLC数据)_s7协议批量读取-CSDN博客这篇博客作为C#的基础系列&#xff0c;和大家分享如何一步步建立一个C#项目完成对S7-1200PLC数据的连续读取。首先…

【AI绘画】FLUX:这款新的人工智能图像生成器非常善于创造人手

FLUX.1 是 Stable Diffusion 的公开重量级继承者&#xff0c;可将文本转化为图像。 FLUX.1 dev 生成图像&#xff1a;“A beautiful queen of the universe holding up her hands, face in the background.”。 就在7月下旬&#xff0c;人工智能初创公司黑森林实验室&#xff…

从零入门CV图像竞赛(2024全球Deepfake攻防挑战赛)

从零入门CV图像竞赛&#xff08;2024全球Deepfake攻防挑战赛&#xff09; Deepfake是什么&#xff1f; Deepfake是一种利用深度学习技术&#xff0c;特别是生成对抗网络&#xff08;GANs&#xff09;来实现视频、音频等多媒体内容的伪造技术。这项技术可以实现对视频中人物的…

【2】Swift Dynamic Island开发

文章目录 先新建一个实时活动组件熟悉下实时活动的代码UI代码解析 灵动岛&#xff08;Dynamic Island&#xff09;和实时活动&#xff08;Live Activities&#xff09;是 iPhone 为了便于用户在退出APP时&#xff0c;仍然能随时关注进行中的活动、高频操作的组件。其中: 灵动岛…

快速体验LLaMA-Factory 私有化部署和高效微调Llama3模型(曙光超算互联网平台异构加速卡DCU)

序言 本文以 LLaMA-Factory 为例&#xff0c;在超算互联网平台SCNet上使用异构加速卡AI 显存64GB PCIE&#xff0c;私有化部署Llama3模型&#xff0c;并对 Llama3-8B-Instruct 模型进行 LoRA 微调、推理和合并。 快速体验基础版本&#xff0c;请参考另一篇博客&#xff1a;快…

栈和队列的区别

简介 栈和队列从定义上来讲&#xff0c;只有一个不同&#xff0c;就是栈是先进后出的&#xff0c;而队列是先进先出的&#xff0c;两者不的不同如下所图所示: 栈和队列的实现 从实现上来说&#xff0c;栈和队列都可以用数组或者链表实现&#xff0c;不过从实现难度和时空复杂…

WEB前端16-Vuex状态管理模式

Vue2-Vuex基础 1.Vuex基本概念 在复杂的前端应用程序中&#xff0c;状态管理变得至关重要。Vuex 是 Vue.js 官方提供的状态管理模式和库&#xff0c;它能帮助我们更好地管理应用程序的状态并实现组件间的通信。本文将介绍 Vuex 的基本概念、核心概念和实际应用。 什么是 Vue…

Vue3炫酷的界面

Vanta.js - Animated 3D Backgrounds For Your Website3D & WebGL Background Animations For Your Websitehttps://www.vantajs.com/?effectbirds需要的安装包 npm install three npm install three0.13.4.0npm install vue3.2.37#Vanta JS 依赖 npm install vanta np…

移情别恋c++ ദ്ദി˶ー̀֊ー́ ) ——1.c++入门(2)

1. 函数重载 C⽀持在同⼀作⽤域中出现同名函数&#xff0c;但是要求这些同名函数的形参不同&#xff0c;可以是参数个数不同或者 类型不同。这样C函数调⽤就表现出了多态⾏为&#xff0c;使⽤更灵活。C语⾔是不⽀持同⼀作⽤域中出现同 名函数的。 #include<iostream> u…

传知代码-半监督学习与数据增强(论文复现)

代码以及视频讲解 本文所涉及所有资源均在传知代码平台可获取 概述 本文复现论文 FixMatch: Simplifying Semi-Supervised Learning with Consistency and Confidence[1] 提出的半监督学习方法。 半监督学习&#xff08;Semi-supervised Learning&#xff09;是一种机器学习…

使用Python库开发Markdown编辑器并将内容导出为图片

简介 在本文中&#xff0c;我们将探索如何使用Python的wxPython库开发一个Markdown编辑器应用程序。这个应用程序不仅能浏览和编辑Markdown文件&#xff0c;还可以将编辑的内容导出为PNG图片。 C:\pythoncode\new\markdowneditor.py 完整代码 import wx import markdown2 im…

前端实现下载word(多个word下载)-- docxtemplater

文章目录 &#x1f50e;什么是docxtemplater&#xff1f;&#x1f47b;docxtemplater语法&#x1f47b;普通插值for循环选择图片&#xff08;&#x1f330;代码&#xff09; &#x1f47b;实现下载&#x1f47b;安装依赖&#x1f330;完整代码关键逻辑解释 &#x1f47b;实现多…

CSP-J 复赛 模拟题 解析版

根据解析写代码1&#xff1a; #include <bits/stdc.h> using namespace std; long long a[101010]; long long b[101010]; int main(){bool flag0;long long t;cin>>t;while(t--){long long n,k;cin>>n>>k;for(int i1;i<n;i){cin>>a[i]>…

kickstart自动安装脚本

1、准备阶段 #开启图形 init 5 ​ #安装带GUI的服务器包组 yum -y groupinstall "Server with GUI" ​ #在xshell做需要加X ssh -Xl root 172.25.254.128 ​ #开启图形 gedit ​ 2、kickstart [rootpxe ~]# cat /root/anaconda-ks.cfg #此文件是在系统安装好后…

大数据Flink(一百零九):阿里云Flink的基本名称概念

文章目录 阿里云Flink的基本名称概念 一、层次结构 二、​​​​​​​​​​​​​​概念说明 1、工作空间&#xff08;Workspace&#xff09; 2、项目空间&#xff08;Namespace&#xff09; 3、资源&#xff08;Resource&#xff09; 4、草稿&#xff08;Draft&#…

将本地微服务发布到docker镜像二:

上一篇文章我们介绍了如何将一个简单的springboot服务发布到docker镜像中&#xff0c;这一篇我们将介绍如何将一个复杂的微服务&#xff08;关联mysql、redis&#xff09;发布到docker镜像。 我们将使用以下两种不同的方式来实现此功能。 redis、mysql、springboot微服务分开…

linux的自动检测的脚本:用于检测应用程序状态的linux脚本

目录 一、要求 1、需求内容 2、分析 二、脚本介绍 1、脚本代码 2、脚本解释 &#xff08;1&#xff09;脚本结构 &#xff08;2&#xff09;应用程序和服务列表 &#xff08;3&#xff09;日志文件路径 &#xff08;4&#xff09;测试 URL 列表 &#xff08;5&#…

智能小程序 Ray 开发面板 SDK —— 无线开关一键执行模板教程(一)

1. 准备工作 前提条件 已阅读 Ray 新手村任务&#xff0c;了解 Ray 框架的基础知识已阅读 使用 Ray 开发万能面板&#xff0c;了解 Ray 面板开发的基础知识 构建内容 在此 Codelab 中&#xff0c;您将利用面板小程序开发构建出一个支持一键执行及自动化的无线开关面板&…