100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > vue3实现滑块验证码

vue3实现滑块验证码

时间:2021-12-29 03:38:14

相关推荐

vue3实现滑块验证码

组件代码

<script setup lang="ts">import { onMounted, reactive, toRefs } from 'vue'const emit = defineEmits(['success','error'])const props = defineProps({top:{type:Number,default:30}})const data = reactive({left:0,btnLeft:0,btnRef:null,maxImgRef:null,minImgRef:null,offsetLeft:0,top:props.top})// 定义节点ref,也可以使用composition api中的ref来定义const {btnRef,maxImgRef,minImgRef} = toRefs(data)onMounted(()=>{// 初始化获取按钮距离左边的宽度,防止滑动的时候闪烁data.offsetLeft = data.btnRef.offsetLeft})const reset = () =>{data.left = 0}const btnDown = (e:any)=>{// 鼠标按下的时候获取按钮距离左边的坐标data.btnLeft = e.pageX - data.btnRef.offsetLeft// 鼠标按下的时候绑定鼠标滑动和鼠标松开事件document.body.addEventListener('mousemove',btnMousemove)document.body.addEventListener('mouseup',btnMouseup)}const btnMousemove = (e:any)=>{// 鼠标距离左边的坐标 - 节点距离左边的距离 - 最开始鼠标按下时候距离左边的距离let x = e.pageX - data.offsetLeft - data.btnLeft// 获取最大可以滑动多远let maxLeft = data.maxImgRef.parentNode.offsetWidth - data.maxImgRef.offsetWidth// 判断临界值,保证不滑出框内if(x <=0){x = 0}else if(x>=maxLeft){x = maxLeft}data.left = x}const btnMouseup = (e:any)=>{// 获取缺的那块的位置let minImgOffsetLeft = data.minImgRef.offsetLeft// 控制区间值let region = 5// 判断移动的最小区间let min = minImgOffsetLeft - region// 判断移动的最大区间let max = minImgOffsetLeft + region// 松开后判断是否验证通过,是不是在这个区间内if(data.left <= max && data.left>= min){emit('success')}else{reset()emit('error')}// 移除鼠标的滑动和松开鼠标事件document.body.removeEventListener('mousemove',btnMousemove)document.body.removeEventListener('mouseup',btnMouseup)}</script><template><div class="imgCheck"><div class="title">拖动下方滑块完成拼图</div><div class="box"><div class="box-content"></div><div class="defect" ref="minImgRef":style="{top:data.top+'px'}"></div><div class="mimImg" :style="{left:data.left+'px',top:data.top+'px'}" ref="maxImgRef"></div></div><div class="slider"><div class="line"></div><div class="btn" @mousedown="btnDown"ref="btnRef":style="{left:data.left+'px'}">|||</div></div></div><button class="resetBtn" @click="reset">重置</button></template><style scoped>.imgCheck{width: 600px;height: 450px;border: 1px solid #ccc;margin: 100px auto 20px;}.title{height: 100px;line-height: 100px;font-size: 16px;font-weight: bold;text-align: center;}.box{height: 300px;background: goldenrod;position: relative;}.box-content{width: 100%;height: 100%;background: goldenrod;}.defect{width: 50px;height: 50px;background: #ccc;position: absolute;top: 80px;left: 520px;}.mimImg{width: 50px;height: 50px;background: green;position: absolute;top: 80px;left: 0;}.slider{position: relative;height: 50px;display: flex;justify-content: center;align-items: center;}.line{height: 10px;background: #ccc;width: 100%;border-radius: 10px;overflow: hidden;display: inline-block;}.btn{position: absolute;top: 50%;left: 0;background: rgb(131, 131, 241);width: 40px;height: 16px;margin-top: -8px;border-radius: 10px;color: #fff;display: flex;justify-content: center;font-size: 12px;align-items: center;cursor: pointer;letter-spacing: 5px;}</style>

父组件调用

<script setup lang="ts">import imgCheck from './components/imgCheck.vue'const success = () =>{alert('验证成功')}const error = () =>{console.log('验证失败')}</script><template><imgCheck :top="60" @success="success" @error="error" /></template>

效果图

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。