vue3.2+ 滑动验证组件,pc/手机通用,即插即用
一、前言二、成果展示三、组件使用四、vue3.2+ 滑动验证组件 源码五、最后,点个赞
一、前言
vue已经更新到3.2+,使用了script的setup属性语法,支持typescript,但是网上已有的大部分滑动验证组件都是旧版本,还不支持触摸,所以决定写一个:
支持vue3.2+语法支持typescript支持pc/手机(自动适配)即插即用
的滑动验证组件,方便大家。当然,这个只是静态的校验,如果需要动态校验,需要和后端配合。
二、成果展示
三、组件使用
import组件,然后
successIcon 成功图标{string} 默认值 ‘iconfont icon-status-nor’successText 成功文字string} 默认值 ‘验证成功’startIcon 开始的图标{string} 默认值 ‘iconfont icon-login-slid’startText 开始的文字{string} 默认值 ‘拖动滑块到最右边’
vue3.2+ 滑动验证组件,pc/手机通用
import { reactive } from 'vue'
import dragVerify from '@/components/dragVerify.vue'
// 提交表单数据
const form = reactive({
isVerifyPass: false, // 滑块验证结果
})
四、vue3.2+ 滑动验证组件 源码
{{ verifyResult ? successText : startText }}
import { ref } from 'vue'
const emit = defineEmits(['update:value'])
defineProps({
value: {
type: Boolean,
defalut: false,
},
// 成功图标
successIcon: {
type: String,
default: 'iconfont icon-status-nor',
},
// 成功文字
successText: {
type: String,
default: '验证成功',
},
// 开始的图标
startIcon: {
type: String,
default: 'iconfont icon-login-slid',
},
// 开始的文字
startText: {
type: String,
default: '拖动滑块到最右边',
},
})
const verifyResult = ref(false) // 验证结果
const isTouch = 'ontouchstart' in document.documentElement
const moveEvent = isTouch ? 'touchmove' : 'mousemove'
const upEvent = isTouch ? 'touchend' : 'mouseup'
// 滑块触摸开始
const onStart = (ev: MouseEvent | TouchEvent) => {
let disX = 0 // 滑块移动距离
const iconWidth = 40 // 滑动图标宽度
const ele = document.querySelector('.drag-verify .block') as HTMLElement
const startX = (ev as MouseEvent).clientX || (ev as TouchEvent).touches[0].pageX
const parentWidth = ele.offsetWidth
const MaxX = parentWidth - iconWidth
if (verifyResult.value) {
return false
}
// 滑块触摸移动
const onMove = (e: MouseEvent | TouchEvent) => {
const endX = (e as MouseEvent).clientX || (e as TouchEvent).touches[0].pageX
disX = endX - startX
if (disX <= 0) {
disX = 0
}
if (disX >= MaxX - iconWidth) {
disX = MaxX
}
ele.style.transition = '.1s all'
ele.style.transform = `translateX(${disX}px)`
}
// 滑块触摸结束
const onEnd = () => {
if (disX !== MaxX) {
ele.style.transition = '.5s all'
ele.style.transform = 'translateX(0)'
} else {
// 执行成功
verifyResult.value = true
emit('update:value', verifyResult.value)
}
document.removeEventListener(moveEvent, onMove)
document.removeEventListener(upEvent, onEnd)
}
document.addEventListener(moveEvent, onMove)
document.addEventListener(upEvent, onEnd)
}
$color-primary: #03c5e5;
@mixin flex {
display: flex;
justify-content: center;
align-items: center;
}
.drag-verify {
width: 100%;
.range {
background-color: #ececee;
position: relative;
border-radius: 4px;
transition: 1s all;
user-select: none;
color: #666;
overflow: hidden;
@include flex;
height: 40px;
&.success {
background-color: $color-primary;
color: #fff;
.text {
position: relative;
z-index: 1;
}
.block i {
color: $color-primary;
}
}
.block {
display: block;
position: absolute;
left: calc(-100% + 40px);
width: 100%;
height: 100%;
background: $color-primary;
border-radius: 4px;
overflow: hidden;
i {
position: absolute;
right: 0;
width: 40px;
height: 100%;
font-size: 20px;
color: #c8c9cc;
background-color: #fff;
border: 1px solid #e5e5e5;
border-radius: 4px;
cursor: pointer;
@include flex;
}
}
}
}
五、最后,点个赞
如果帮到你,点个赞再走!
文章来源
发表评论