Vue项目中手搓滑动校验模块-demo


实现代码
SliderCheck.vue
<template><div class="drag" ref="dragDiv"><div class="drag_bg" ref="dragBg"></div><div class="drag_text" ref="dragText">{{ confirmWords }}</div><divref="moveDiv"@mousedown="mouseDownFn($event)"@touchstart="touchStartFn($event)":class="{ handler_ok_bg: confirmSuccess }"class="handler handler_bg flx-center"style="position: absolute; top: -1px; left: -1px"><icon-arrow-right class="base-icon"></icon-arrow-right></div></div>
</template><script setup lang="ts">
// 距离屏幕左端距离
const beginClientX = ref(0)
// 触发拖动状态 判断
const mouseMoveState = ref(false)
// 拖动最大宽度,依据滑块宽度算出来的
const maxWidth = ref("")
// 滑块文字
const confirmWords = ref("请按住滑块,拖动到最右边")
// 验证成功判断
const confirmSuccess = ref(false)
const dragDiv = ref(null)
const dragBg = ref(null)
const dragText = ref(null)
const moveDiv = ref(null)const emit = defineEmits(["status-changed"])// 验证成功函数
const successFunction = () => {confirmSuccess.value = trueconfirmWords.value = "验证通过"// 移除事件监听document.getElementsByTagName("html")[0].removeEventListener("mousemove", mouseMoveFn)document.getElementsByTagName("html")[0].removeEventListener("mouseup", moseUpFn)document.getElementsByTagName("html")[0].removeEventListener("touchmove", touchMoveFn)document.getElementsByTagName("html")[0].removeEventListener("touchend", touchEndFn);(dragText.value as any)!.style.color = "#fff";(moveDiv.value as any).style.left = `${maxWidth.value}px`;(dragBg.value as any).style.width = `${maxWidth.value}px`emit("status-changed", "success")
}// mouse事件 鼠标按下 开始
const mouseDownFn = (e: any) => {if (!confirmSuccess.value) {e.preventDefault && e.preventDefault() // 阻止文字选中等 浏览器默认事件mouseMoveState.value = truebeginClientX.value = e.clientX}
}// mousemove事件 移动
const mouseMoveFn = (e: any) => {if (mouseMoveState.value) {let width = e.clientX - beginClientX.valueif (width > 0 && width <= Number(maxWidth.value)) {;(moveDiv.value as any).style.left = `${width}px`;(dragBg.value as any).style.width = `${width}px`} else if (width > Number(maxWidth.value)) {successFunction()}}
}
// mouseup事件 结束
const moseUpFn = (e: any) => {mouseMoveState.value = falseconst width = e.clientX - beginClientX.valueif (width < Number(maxWidth.value)) {;(moveDiv.value as any).style.left = `${0}px`;(dragBg.value as any).style.width = `${0}px`}
}// =====================兼容移动端移动事件=============================
// touch事件 按下 开始
const touchStartFn = (e: TouchEvent) => {if (!confirmSuccess.value) {e.preventDefault()mouseMoveState.value = truebeginClientX.value = e.touches[0].clientX}
}
// touch事件 移动
const touchMoveFn = (e: TouchEvent) => {if (mouseMoveState.value) {let width = e.touches[0].clientX - beginClientX.valueif (width > 0 && width <= Number(maxWidth.value)) {;(moveDiv.value as any).style.left = `${width}px`;(dragBg.value as any).style.width = `${width}px`} else if (width > Number(maxWidth.value)) {successFunction()}}
}
// touch事件 结束
const touchEndFn = (e: TouchEvent) => {mouseMoveState.value = falseconst width = e.changedTouches[0].clientX - beginClientX.valueif (width < Number(maxWidth.value)) {;(moveDiv.value as any).style.left = `${0}px`;(dragBg.value as any).style.width = `${0}px`}
}
// =====================兼容移动端移动事件end=============================onMounted(() => {maxWidth.value = String((dragDiv.value as any)!.clientWidth - (moveDiv.value as any)!.clientWidth - 1)document.getElementsByTagName("html")[0].addEventListener("mousemove", mouseMoveFn)document.getElementsByTagName("html")[0].addEventListener("mouseup", moseUpFn)document.getElementsByTagName("html")[0].addEventListener("touchmove", touchMoveFn)document.getElementsByTagName("html")[0].addEventListener("touchend", touchEndFn)
})
</script>
<style scoped>
.drag {position: relative;box-sizing: border-box;width: 100%;height: 39px;line-height: 38px;text-align: center;background-color: rgb(204 204 204 / 20%);border: 1px solid #cccccc;border-radius: 4px;
}
.handler {box-sizing: border-box;width: 46px;height: 38px;cursor: move;border: 1px solid #cccccc;border-radius: 4px;
}
.handler_bg {background: #ffffff;
}
.handler_ok_bg {background: #ffffff;border-top-left-radius: 0;border-bottom-left-radius: 0;
}
.drag_bg {width: 0;height: 38px;background-color: #0cc399;border-radius: 4px 0 0 4px;
}
.drag_text {position: absolute;top: 0;width: 100%;font-size: var(--el-font-size-base);font-weight: 400;color: var(--el-color-info-light-3);text-align: center;user-select: none;
}
</style>
使用
<template><a-form class="large-form"><a-form-item><SliderCheck ref="sliderCheckRef" @status-changed="changeSliderStatus"></SliderCheck></a-form-item></a-form>
</template><script setup lang="ts">
const sliderCheckRef = ref()
const isValidated = ref(false)
const asyncPhoneIsValid = ref(false)
const changeSliderStatus = async (status: string) => {isValidated.value = status === "success"try {asyncPhoneIsValid.value = validateInfos.mobile.validateStatus === "success"} catch (err: any) {asyncPhoneIsValid.value = false}
}
</script><style lang="scss" scoped>
</style>
相关文章:
Vue项目中手搓滑动校验模块-demo
实现代码 SliderCheck.vue <template><div class"drag" ref"dragDiv"><div class"drag_bg" ref"dragBg"></div><div class"drag_text" ref"dragText">{{ confirmWords }}</di…...
Socket如何实现客户端和服务器间的通信
Socket 是实现网络通信的一种机制,它允许在不同主机之间的进程通过网络进行数据交换。下面我将简要介绍如何使用 Socket 实现客户端和服务器间的通信。 客户端-服务器通信步骤: 服务器端: 创建服务器端 Socket: 服务器端通过创…...
基于Spring boot + Vue的校园论坛
作者的B站地址:程序员云翼的个人空间-程序员云翼个人主页-哔哩哔哩视频 csdn地址:程序员云翼-CSDN博客 1.项目技术栈: 前后端分离的项目 后端:Springboot MybatisPlus 前端:Vue ElementUI 数据库: …...
RabbitMQ高级特性 - 生产者消息确认机制
文章目录 生产者消息确认机制概述confirm 代码实现return 代码实现 生产者消息确认机制 概述 为了保证信息 从生产者 发送到 队列,因此引入了生产者的消息确认机制. RabbitMQ 提供了两种解决方案: 通过事务机制实现.通过发送确认机制(confi…...
webpack的loader机制
webpack的loader机制 loader本质上就是导出函数的JavaScript模块。导出的函数,可以用来实现内容的转换。 /* * param{string|Buffer} content 源文件的内容 * param{object} [map] SourceMap数据 * param{any} [meta] meta数据,可以是任何数据 * */ fu…...
(STM32笔记)十一、通过EXTI外部中断实现 按键控制LED
我用的是正点的STM32F103来进行学习,板子和教程是野火的指南者。 之后的这个系列笔记开头未标明的话,用的也是这个板子和教程。 十一、通过EXTI外部中断实现 按键控制LED 十一、通过EXTI外部中断实现 按键控制LED1、按键模块按键原理图按键程序思路 2、中…...
假如家里太大了,wifi连不上了怎么办
最近有个土豪朋友抱怨,他家里太大了,一个路由器的Wi-Fi信号根本无法覆盖他们家的每个房间,都没办法上网看奥运会比赛了。(还好我是穷人,就没有这种烦恼T_T)。 然后我问他为何不用一个路由器作主路由器&…...
elementPlus 设置el-input文本域固定高度和禁止下拉
elementPlus 设置el-input文本域固定高度和禁止下拉 话不多说直接上代码 // resize"none" 禁止下拉<el-inputv-model"textarea"style"width: 240px"type"textarea"resize"none"placeholder"请输入"/>// 设…...
(转)领导人必过的三道关
为什么企业领导人享受优厚的待遇,为什么董事会对企业领导人千挑万选?因为企业生命如此脆弱,据美国《财 富》杂志报道,世界500强企业平均寿命40年,世界1000强企业平均寿命30年,一般跨国公司平均寿命10年。而就是这脆弱…...
速盾:cdn可以定时刷新缓存吗?
CDN(Content Delivery Network)是一种通过在全球各地分布的服务器上缓存和传送网站内容的技术,以提高用户访问速度和降低服务器负载。CDN的缓存机制可以减少用户对源服务器的请求次数,从而提高网站的响应速度和性能。但是…...
代码随想录算法训练营第二十九天| 62.不同路径、63. 不同路径 II
写代码的第二十九天 继续动归!!! 62.不同路径 思路 解决问题1:dp[i][j]的的含义是什么?本题给的是一个二维的表,判断从左上角走到右下角有多少种路径,所以dp应该是二维数组,dp[i]…...
Go+Redis零基础到用户管理系统API实战_20240730 课程笔记
概述 如果您没有Golang的基础,应该学习如下前置课程。 Golang零基础入门Golang面向对象编程Go Web 基础Go语言开发REST API接口_20240728Go语言操作MySQL开发用户管理系统API教程_20240729Redis零基础快速入门_20231227 基础不好的同学每节课的代码最好配合视频进…...
ScreenAgent:基于LVLM的计算机控制智能体
ScreenAgent : A Vision Language Model-driven Computer Control Agent 论文链接: https://arxiv.org/abs/2402.07945https://arxiv.org/abs/2402.07945IJCAI 2024 1.概述 大型语言模型(LLM),诸如ChatGPT与GPT-4,在自然语言处理领域(涵盖生成、理解及对话等任务)展现出…...
谷粒商城实战笔记-129-商城业务-商品上架-nested数据类型场景
文章目录 扁平化处理扁平化处理导致的检索问题 解决方案:使用 nested 结构 在es的数据类型中有一个nested类型,本讲将重点讨论这个类型。 扁平化处理 PUT my_index/doc/1 {"group" : "fans","user" : [{"first&quo…...
axios请求响应拦截器
目录 axios-拦截器 拦截器的作用 请求拦截器-基本写法: axios请求拦截器-统一设置token 需求: 核心步骤: 关键代码: 响应拦截器-基本写法: axios响应拦截器-统一处理token失效 需求: 核心步骤: 关键代码: axios响应拦截器-数据剥离 需求: 核心步骤: 关键代码: ax…...
Python 中单例模式实现的几种方式
在设计模式中,单例模式是经常被提及和使用的一种模式。它保证一个类只有一个实例,并提供全局访问点。在Python中,有多种实现单例模式的方法。那么,如何选择合适的方法来实现单例模式呢? 单例模式在Python中的几种实现方…...
mysql数据库触发器同步数据
首先检查数据源库是否支持触发器,show ENGINES,如果FEDERATED是NO,表示未开启,如需开启,再mysql配置文件中,添加federated配置到mysqld下面。 一、同服务器不同库触发器同步,这里只举例插入数据…...
Prometheus-v2.45.0+Grafana+邮件告警
目录 普罗米修斯监控架构介绍 Prometheus 监控架构 1. 数据抓取(Scraping) 2. 时序数据库(TSDB) 3. 数据模型 4. PromQL 查询语言 5. 告警(Alerting) 6. Alertmanager 7. 可视化(Visu…...
LeetCode——572. 另一颗树的子树
通过万岁!!! 题目:给你两棵树,然后问subRoot是不是root的子树。也就是root某个节点的所有孩子节点在值和结构上完全与subRoot相同。思路:我的思路比较简单,就是遍历root,遇到root中…...
Spring Boot整合MyBatis-Flex
说明:MyBatis-Flex(官网地址:https://mybatis-flex.com/),是一款数据访问层框架,可实现项目中对数据库的访问,类比MyBatis-Plus。本文介绍,在Spring Boot项目整合MyBatis-Flex。 创…...
Arduino红外遥控库:让硬件设备听懂遥控器的语言
Arduino红外遥控库:让硬件设备听懂遥控器的语言 【免费下载链接】Arduino-IRremote Infrared remote library for Arduino: send and receive infrared signals with multiple protocols 项目地址: https://gitcode.com/gh_mirrors/ar/Arduino-IRremote 你是…...
从旋转矩阵到李代数:三维空间刚体运动的速度解析与几何直观
1. 刚体运动的基本概念:从旋转轴到角速度 想象你手里握着一个魔方,当你想让它旋转时,总会下意识地找一个转动轴。这个简单的动作背后,藏着描述三维空间刚体运动的核心数学工具。在机器人控制和计算机视觉领域,我们经常…...
快速SEO排名服务需要多长时间见效_快速SEO排名服务有哪些常见的手段
快速SEO排名服务需要多长时间见效 在当今数字化时代,网站的在线可见度对于企业的成功至关重要。快速SEO排名服务应运而生,旨在帮助企业尽快在搜索引擎上获得更好的排名,从而提高流量和业务。但是,很多人都会疑惑,快速…...
微信小程序框架详解
小程序包含一个描述整体程序的app实例和多个描述页面的page。其中app由三个文件构成:公共配置app.json、公共样式app.wxss、主体逻辑app.js。每个page最多由四个文件构成:页面配置page.json、页面结构page.wxml、页面样式page.wxss、页面主体逻辑page.js。 微信小程序的主体部…...
3大维度解析Source Han Serif CN如何重塑中文字体应用生态
3大维度解析Source Han Serif CN如何重塑中文字体应用生态 【免费下载链接】source-han-serif-ttf Source Han Serif TTF 项目地址: https://gitcode.com/gh_mirrors/so/source-han-serif-ttf 价值解析:从商业、技术、设计维度重新定义开源字体价值 商业价值…...
国标参考文献高效排版解决方案:零门槛工具助你轻松应对学术写作
国标参考文献高效排版解决方案:零门槛工具助你轻松应对学术写作 【免费下载链接】gbt7714-bibtex-style GB/T 7714-2015 BibTeX Style 项目地址: https://gitcode.com/gh_mirrors/gb/gbt7714-bibtex-style 1. 解决国标排版痛点的3个核心优势 学术写作中&…...
深度解析ViGEmBus:如何高效构建Windows内核级游戏控制器模拟框架
深度解析ViGEmBus:如何高效构建Windows内核级游戏控制器模拟框架 【免费下载链接】ViGEmBus Windows kernel-mode driver emulating well-known USB game controllers. 项目地址: https://gitcode.com/gh_mirrors/vi/ViGEmBus ViGEmBus是一款基于Windows内核…...
Fish Speech 1.5快速上手:一键部署,轻松实现中英日韩13种语言语音合成
Fish Speech 1.5快速上手:一键部署,轻松实现中英日韩13种语言语音合成 1. 为什么选择Fish Speech 1.5? 上周我帮一个跨国团队部署语音合成系统,他们需要在24小时内完成中英日韩四语的商品介绍语音生成。传统方案需要部署多个语音…...
Qwen3-14B向量数据库集成:Chroma/Milvus接入与混合检索配置
Qwen3-14B向量数据库集成:Chroma/Milvus接入与混合检索配置 1. 引言:为什么需要向量数据库集成 当你部署了强大的Qwen3-14B大模型后,很快会发现一个关键问题:如何让模型记住并快速检索大量知识?这就是向量数据库的价…...
Hunyuan-MT-7B GPU部署:Pixel Language Portal在单卡A10上并发处理16路实时语音翻译压测报告
Hunyuan-MT-7B GPU部署:Pixel Language Portal在单卡A10上并发处理16路实时语音翻译压测报告 1. 项目背景与核心价值 Pixel Language Portal(像素语言跨维传送门)是一款基于Tencent Hunyuan-MT-7B大模型构建的创新翻译工具。与传统翻译软件…...
