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。 创…...
Python|GIF 解析与构建(5):手搓截屏和帧率控制
目录 Python|GIF 解析与构建(5):手搓截屏和帧率控制 一、引言 二、技术实现:手搓截屏模块 2.1 核心原理 2.2 代码解析:ScreenshotData类 2.2.1 截图函数:capture_screen 三、技术实现&…...
Linux应用开发之网络套接字编程(实例篇)
服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...
通过Wrangler CLI在worker中创建数据库和表
官方使用文档:Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后,会在本地和远程创建数据库: npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库: 现在,您的Cloudfla…...
TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案
一、TRS收益互换的本质与业务逻辑 (一)概念解析 TRS(Total Return Swap)收益互换是一种金融衍生工具,指交易双方约定在未来一定期限内,基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...
分布式增量爬虫实现方案
之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面,避免重复抓取,以节省资源和时间。 在分布式环境下,增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路:将增量判…...
2025季度云服务器排行榜
在全球云服务器市场,各厂商的排名和地位并非一成不变,而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势,对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析: 一、全球“三巨头”…...
【分享】推荐一些办公小工具
1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由:大部分的转换软件需要收费,要么功能不齐全,而开会员又用不了几次浪费钱,借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...
push [特殊字符] present
push 🆚 present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中,push 和 present 是两种不同的视图控制器切换方式,它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...
Razor编程中@Html的方法使用大全
文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...
Rust 开发环境搭建
环境搭建 1、开发工具RustRover 或者vs code 2、Cygwin64 安装 https://cygwin.com/install.html 在工具终端执行: rustup toolchain install stable-x86_64-pc-windows-gnu rustup default stable-x86_64-pc-windows-gnu 2、Hello World fn main() { println…...
