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。 创…...
微信小程序之bind和catch
这两个呢,都是绑定事件用的,具体使用有些小区别。 官方文档: 事件冒泡处理不同 bind:绑定的事件会向上冒泡,即触发当前组件的事件后,还会继续触发父组件的相同事件。例如,有一个子视图绑定了b…...
反向工程与模型迁移:打造未来商品详情API的可持续创新体系
在电商行业蓬勃发展的当下,商品详情API作为连接电商平台与开发者、商家及用户的关键纽带,其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息(如名称、价格、库存等)的获取与展示,已难以满足市场对个性化、智能…...
Nuxt.js 中的路由配置详解
Nuxt.js 通过其内置的路由系统简化了应用的路由配置,使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...
[Java恶补day16] 238.除自身以外数组的乘积
给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O(n) 时间复杂度…...
Angular微前端架构:Module Federation + ngx-build-plus (Webpack)
以下是一个完整的 Angular 微前端示例,其中使用的是 Module Federation 和 npx-build-plus 实现了主应用(Shell)与子应用(Remote)的集成。 🛠️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...
让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比
在机器学习的回归分析中,损失函数的选择对模型性能具有决定性影响。均方误差(MSE)作为经典的损失函数,在处理干净数据时表现优异,但在面对包含异常值的噪声数据时,其对大误差的二次惩罚机制往往导致模型参数…...
JavaScript 数据类型详解
JavaScript 数据类型详解 JavaScript 数据类型分为 原始类型(Primitive) 和 对象类型(Object) 两大类,共 8 种(ES11): 一、原始类型(7种) 1. undefined 定…...
宇树科技,改名了!
提到国内具身智能和机器人领域的代表企业,那宇树科技(Unitree)必须名列其榜。 最近,宇树科技的一项新变动消息在业界引发了不少关注和讨论,即: 宇树向其合作伙伴发布了一封公司名称变更函称,因…...
PostgreSQL——环境搭建
一、Linux # 安装 PostgreSQL 15 仓库 sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-$(rpm -E %{rhel})-x86_64/pgdg-redhat-repo-latest.noarch.rpm# 安装之前先确认是否已经存在PostgreSQL rpm -qa | grep postgres# 如果存在࿰…...
华为OD机试-最短木板长度-二分法(A卷,100分)
此题是一个最大化最小值的典型例题, 因为搜索范围是有界的,上界最大木板长度补充的全部木料长度,下界最小木板长度; 即left0,right10^6; 我们可以设置一个候选值x(mid),将木板的长度全部都补充到x,如果成功…...
