news 2026/9/8 17:39:08

SL-WX-Captcha 行为验证组件(三合一)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
SL-WX-Captcha 行为验证组件(三合一)

SL-WX-Captcha 行为验证组件(三合一)

插件市场
操作视频

组件简介

单一组件统一支持三种主流前端行为验证方式,通过mode属性零切换:

  • slide滑动验证:经典滑块,按住并拖动到底部最右侧即视为通过,失败自动回弹。

  • puzzle拼图验证:背景图上随机生成一个缺口位置,拖动下方滑块让图片拼图块精准对齐缺口,容差可配置。

  • click顺序点字验证:背景图上随机散布多个汉字(目标字 + 干扰字),用户按提示依次点击所有目标字(2~5 个可配)。

组件内部已兼容H5(鼠标 mousedown/move/up)微信小程序(touchstart/move/end)两套事件链路,失败/成功回调、刷新、关闭、容差 / 目标字数等全部参数化可控制。

注:当前背景图使用picsum.photos随机种子作为纯前端 mock 演示;生产环境中建议由后端生成带签名 / 随机水印的验证图与答案,并在success回调里携带后端校验。

目录结构

components/SL-WX-Captcha └── SL-WX-Captcha.vue

三种模式对比

模式值名称成功判定失败后处理
slide滑动验证滑块进度 ≥ 98%(即已滑到最右,自动吸附 100%)400ms easeOutQuad 回弹到 0
puzzle拼图验证`拼图块中心 − 缺口中心
click顺序点字依次点中所有目标字,任意一步点错立即失败(也支持「确认」按钮手动提交)700~900ms 自动清空重试

实现要点 & 修复日志

滑动 / 拼图滑块显示与拖拽可用修复

问题修复方案
滑块初始不可见(slideX=0时 thumb 完全在轨道外)原写法left: X%; transform: translate(-100%, 0)叠加时,X=0 → translate(-100%)会把 thumb 向左平移一个 thumb 自身宽度挪到轨道外。改为纯像素left: Npx+top:50%; translateY(-50%)垂直居中slideThumbPx / puzzleThumbPx直接从 0 线性增长到轨道宽 - thumb 宽,保证两端视觉与比例完全对齐。
拼图块无内容、跟缺口对不上原写法里.sl-puzzle-piece__imgwidth:100% mode=aspectFill,展示的是拼图块左上角对应底图的 (0,0) 位置——根本不对应缺口的像素。改为:piece 里的<image>宽高强制等于舞台宽高,再transform: translate(-pieceLeft, -pieceTop)反向偏移,这样 piece 滑到哪就显示底图对应哪一像素,对齐缺口时内容完全吻合。
缺口形状不明显、不显示原缺口只是一个半透明方块,不够像拼图。改为clip-path: polygon()切出「正方形主体 + 右侧半圆凸块」的经典拼图形状,gap(缺口蒙版)和 piece(拼图块)共用同一份 clip-path,形状完全吻合。
首次渲染拖不动_sliderWidth依赖 SelectorQuery 异步回调结果,mounted首次 touchmove 时回调可能还没返回 → 0 导致 dx 被除。onSlideStart / onPuzzleStart里先调用_ensureSizesFallback()widthprop 先兜底换算一套可用的轨道/thumb 尺寸,保证拖拽启动瞬间就有正确行程。
H5 拖出滑块外"卡住手势"在组件mounteddocument.addEventListener('mousemove' / 'mouseup')beforeDestroy统一解绑,避免 mousedown 后拖到滑块外松开导致的"再按下去无响应"。
click 模式点字事件平台差异小程序端用@touchend+changedTouches[0];H5 端单独绑定@tap.stop.prevente.clientX/Y,避免某一端取不到坐标。

失败回弹曲线

slide / puzzle 失败后不再用setTimeout + 一次性跳回,改用requestAnimationFrame + easeOutQuad逐帧回弹到 0,视觉更自然。progress(fail 回调)为换算后的百分比,便于日志。

Props

属性类型默认值说明
modeString'slide'验证模式:slide/puzzle/click
widthNumber|String620组件宽度;Number 视为 rpx,String 直接作为 CSS 值
puzzleHeightNumber320拼图 / 点字模式图片舞台高度(rpx)
trackHeightNumber72滑块条高度(rpx)
radiusNumber16拼图 / 点字模式圆角(rpx)
pieceSizeNumber100拼图块边长(rpx),建议为舞台宽度的 1/5~1/6
puzzleToleranceNumber4拼图容差(像素 px):拼图块中心与缺口中心的像素差。生产推荐 24px,宽松体验 68px
slideLabelString'请按住滑块,拖动到最右边'模式 1 的提示文案
targetCountNumber3模式 3 的目标文字数量,必须为 2~5。总随机字数 =targetCount + distractCount
distractCountNumber4模式 3 的干扰字数量
showHeaderBooleantrue是否显示顶部标题与刷新栏
showCloseBooleanfalse是否在顶部栏显示「✕」关闭按钮
titleString''自定义顶部标题,留空则根据模式自动取「滑动验证 / 补全图片验证 / 文字顺序验证」

Events

事件名回调参数说明
success{ mode, type, ...payload }验证通过触发,type为对应模式名:slide/puzzle/click
fail{ mode, type, ...payload }验证失败触发
refresh{ mode }点击顶部刷新图标(⟳)触发
close-点击顶部关闭按钮(✕)触发,需要showClose = true

success / fail 的 payload 详情

// mode = 'slide'success:{mode:'slide',type:'slide'}fail:{mode:'slide',type:'slide',progress:Number}// progress 失败时的进度 0~100// mode = 'puzzle'success:{mode:'puzzle',type:'puzzle',diff:1.3,tolerance:4}// diff=像素偏差,tolerance=props设定fail:{mode:'puzzle',type:'puzzle',diff:18.6,tolerance:4}// mode = 'click'success:{mode:'click',type:'click',seq:[0,1,2]}// seq=用户依次点击的目标索引fail:{mode:'click',type:'click',reason:'wrong-order-or-miss'|'incomplete'}

对外方法

通过$refs.captcha.xxx()调用:

方法名说明
onRefresh()与点击顶部刷新按钮等效:重置所有状态、重新随机背景图、缺口位置、点字分布。模式 2 / 3 切换参数(如 targetCount)后建议手动调用一次。
onClose()触发close事件。
noop()空函数,用作事件占位。

使用示例

示例 1:基础滑块验证(登录/注册前)

<template> <view> <sl-wx-captcha ref="cap" mode="slide" :width="660" slide-label="请按住滑块,向右拖动完成验证" @success="onCapOk" @fail="onCapFail" /> </view> </template> <script> import SlWxCaptcha from '@/components/SL-WX-Captcha/SL-WX-Captcha.vue' export default { components: { SlWxCaptcha }, methods: { onCapOk() { uni.showToast({ title: '验证通过,正在登录', icon: 'none' }) this.submitLogin() // 验证成功后再调用登录接口 }, onCapFail(e) { console.log('滑块未到底:', e.progress + '%') } } } </script>

示例 2:拼图验证(容差 6px,较宽松)

<template> <sl-wx-captcha ref="cap" mode="puzzle" :puzzle-tolerance="6" :width="620" :radius="20" @success="onSuccess" @fail="onFail" @refresh="onRefresh" /> </template>

示例 3:顺序点字(4 字验证,作为重要操作二次确认)

<template> <sl-wx-captcha ref="cap" mode="click" :target-count="4" :distract-count="5" :show-close="true" title="请先完成二次验证" @success="onPay" @close="onCancel" /> </template> <script> export default { methods: { onPay(e) { // e.seq 可上报后端进行二次审计 console.log('验证通过,点字顺序:', e.seq) this.confirmPay() }, onCancel() { uni.navigateBack() } } } </script>

示例 4:弹层(uni-popup / 自定义遮罩)内使用 + 关闭按钮 + 刷新

<template> <view class="mask" @tap="close"></view> <view class="pop" @tap.stop=""> <sl-wx-captcha ref="cap" :mode="mode" :show-close="true" @success="onOk" @close="close" @refresh="(e)=>console.log('刷新了', e.mode)" /> </view> </template>

实现要点(可二次开发)

  1. 事件链路

    • 滑块 / 拼图使用@touchstart/move/end/capture.stop.prevent保证在小程序端优先锁定手势,避免父容器 scroll-view 把横拖误识别为纵向滚动。

    • H5 端在组件mounteddocument级绑定mousemove / mouseupbeforeDestroy自动解绑,防止鼠标抬出滑块外导致"卡着手势"。

  2. 测量prepareStage()中用uni.createSelectorQuery().in(this)取舞台和滑块条的真实像素宽度,兼容不同宽度配置下拼图比例/滑块行程正确。

  3. 拼图实现

    • 用「相同背景图 × 2」一张铺底,另一张放入.sl-puzzle-pieceoverflow:hidden+ 固定宽高 = 拼图块),通过 piece 的top/left与滑块位置联动实现"切片效果",无需后端合成拼图。

    • 缺口用半透明白色蒙版 + 内描边,提示用户拼图目标位置。

  4. 点字命中判定:以用户点击像素为圆心,半径 26px 范围内取最近字作为命中候选,字的样式随机倾斜/颜色/大小/字体,贴近真实点字验证码观感。

  5. 无障碍与反馈:每次失败或成功都会在舞台顶部弹出半透明遮罩(绿色通过/红色失败),并且统一触发success/fail事件便于接入业务。

注意事项

  1. 拼图背景图域名白名单:如果使用小程序端,请在微信公众平台配置picsum.photos为合法 downloadFile 域名;生产时换成自己的 OSS/CDN 即可。
  2. 图片加载失败兜底onPuzzleImgError已经监听了底图失败(会走白底 + 缺口形状),交互依然可用,建议后端额外监控图片 404。
  3. 拼图容差与用户体验puzzleTolerance建议 2~4(难)~ 6~8(宽松),超过 10px 基本等同于无校验。
  4. 不要把安全校验放前端:本组件实现的是前端交互基础判定,在前端判定成功后建议把diff/seq/progress等摘要一并上报后端,使用后端接口做最终决策(或使用加密 token),避免被自动化脚本绕过。
  5. mode 切换时自动重绘:组件已 watchmode,切换会立即resetAll + prepareStage,无需手动刷新;但如果是在同一 mode 下改了targetCount / puzzleTolerance等参数,建议调用this.$refs.cap.onRefresh()手动刷新一次题目。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/8 17:36:24

用Claude Code Skill打造嵌入式AI管家:编译、烧录到波形分析

1. 为什么说嵌入式开发终于等来了“AI 管家” 干嵌入式这行的人都有个共同感受&#xff1a;**这边的工具链太散了。**写代码用 VSCode&#xff0c;编译靠 CMake 加交叉编译器&#xff0c;烧录要敲 OpenOCD 命令&#xff0c;查寄存器得翻 datasheet&#xff0c;看波形又要切到逻…

作者头像 李华
网站建设 2026/9/8 17:35:57

基于光伏出力利用率的充电站能量调度策略与工程实践

给充电站装光伏&#xff0c;听起来是一笔稳赚的账&#xff1a;白天阳光最猛的时候正好是工商业电价的高峰&#xff0c;光伏发的电直接充进车端&#xff0c;每一度电都省下了从电网买电的钱。可真到现场盯过三个月&#xff0c;你会发现“光伏好、充电需求也好”的日子只存在于PP…

作者头像 李华
网站建设 2026/9/8 17:35:10

pot-desktop:跨平台划词翻译与截图 OCR,三端一条命令装好

pot-desktop&#xff1a;跨平台划词翻译与截图 OCR&#xff0c;三端一条命令装好 【免费下载链接】pot-desktop &#x1f308;一个跨平台的划词翻译和OCR软件 | A cross-platform software for text translation and recognition. 项目地址: https://gitcode.com/GitHub_Tren…

作者头像 李华