@punish/slider-captcha
v1.0.0
Published
vue3 滑块验证码组件
Maintainers
Readme
@punish/slider-captcha
一个功能强大的 Vue 3 滑块验证码组件,支持自定义样式和事件。
📖 文档
完整的 API 文档和在线演示:Documents
✨ 功能特性
- 🚀 轻量级,仅依赖 Vue 3
- 🎨 支持自定义滑块轨道、滑块按钮样式
- 🔄 自定义样式和事件
- 📱 支持移动端触摸事件
- 🧩 支持自定义验证成功/失败提示插槽
- 🔧 提供组件实例方法(reset 重置、tracks 轨迹数据)
安装
npm install @punish/slider-captcha- 注意: import "@punish/slider-captcha/dist/style.css"; // 如果需要样式 (SSR OR SSG 建议引入, 避免页面样式闪烁)
- 优势: 无需手动引入样式文件 且 按需加载
快速开始
全局注册
import { createApp } from "vue";
import SliderCaptcha from "@punish/slider-captcha";
import "@punish/slider-captcha/dist/style.css"; // SSR/SSG 建议引入
const app = createApp(App);
app.use(SliderCaptcha);局部注册
<script setup lang="ts">
import { SliderCaptcha } from "@punish/slider-captcha";
</script>基础用法
<template>
<SliderCaptcha
:background="bgImage"
:block="blockImage"
:verify="handleVerify"
@success="onSuccess"
@fail="onFail"
@change="onChange"
/>
</template>
<script setup lang="ts">
import { SliderCaptcha } from "@punish/slider-captcha";
import type { SliderCaptchaTrackItem } from "@punish/slider-captcha";
const bgImage = "https://example.com/bg.jpg"; // 应从服务端获取
const blockImage = "https://example.com/block.png"; // 应从服务端获取
const handleVerify = async (last: SliderCaptchaTrackItem) => {
// 自定义验证逻辑,返回 true/false
return last.xPercent > 80; // 应 请求 服务端接口 , 将 last.xPercent 作为参数 (也可能包含其他 服务端所需要的额外数据), 根据服务端验证结果 返回 true/false。 true 表示验证成功,false 表示验证失败。
};
const onSuccess = () => {
console.log("验证成功");
};
const onFail = () => {
console.log("验证失败");
};
const onChange = (tracks: SliderCaptchaTrackItem[]) => {
console.log("滑动轨迹:", tracks);
};
</script>API
Props
| 参数 | 说明 | 类型 | 默认值 |
| ----------------- | ------------------------------------------------------------------ | ----------------------------------------------------------------- | -------------------- |
| background | 背景图片地址(必填) | string | — |
| block | 滑块图片地址(必填) | string | — |
| width | 容器宽度(px) | number | — |
| blockTop | 滑块图距离顶部的距离(像素,基于原始图片尺寸) | number | 0 |
| verify | 验证函数,接收最后一个轨迹点,返回 boolean 或 Promise<boolean> | (option: SliderCaptchaTrackItem) => boolean \| Promise<boolean> | — |
| trackBlockBg | 滑块轨道背景色 | string | #f5f5f5 |
| trackBg | 滑块已滑动区域的背景色 | string | rgba(26,23,27,0.1) |
| trackClass | 滑块轨道自定义类名 | string | "" |
| trackThumbClass | 滑块按钮自定义类名 | string | "" |
Events
| 事件名 | 说明 | 回调参数 |
| --------- | ------------------ | -------------------------- |
| success | 验证成功时触发 | — |
| fail | 验证失败时触发 | — |
| change | 滑动过程中实时触发 | SliderCaptchaTrackItem[] |
插槽
| 插槽名 | 说明 |
| ---------------- | -------------------------------------- |
| default | 自定义滑块按钮内容(默认显示箭头图标) |
| verify-success | 验证成功时的提示内容 |
| verify-fail | 验证失败时的提示内容 |
方法
通过 ref 获取组件实例后,可调用以下方法:
| 方法名 | 说明 | 类型 |
| -------- | ------------------------------ | -------------------------- |
| reset | 重置滑块状态 | () => void |
| tracks | 获取当前滑动轨迹数据(响应式) | SliderCaptchaTrackItem[] |
<template>
<SliderCaptcha ref="captchaRef" :background="bg" :block="block" :verify="verify" />
<button @click="handleReset">重置</button>
</template>
<script setup lang="ts">
import { ref } from "vue";
import { SliderCaptcha } from "@punish/slider-captcha";
const captchaRef = ref();
const handleReset = () => {
captchaRef.value?.reset();
};
</script>自定义样式示例
<template>
<div style="position: relative; width: 600px; margin: 0 auto">
<SliderCaptcha
ref="captchaRef"
:background="captchaData.backgroundImage"
:block="captchaData.sliderImage"
:verify="verifyCaptcha"
track-bg="#65CD81"
track-thumb-class="track-thumb"
track-class="track"
@success="onVerifySuccess"
>
<template #default>
<img src="/svg/double-arrow-right.svg" alt="." style="width: 24px; height: 24px" />
</template>
</SliderCaptcha>
<Loading :visible="captchaVerifying" dot-color="red" dot-size="60px" dot-gap="60px" amplitude="80px" />
</div>
</template>
<script setup>
import { Loading } from "@a-drowned-fish/rox-v";
import { SliderCaptcha } from "@punish/slider-captcha";
interface CaptchaInfo {
backgroundImage: string;
captchaId: string;
sliderImage: string;
}
const captchaData = ref<CaptchaInfo | undefined>(undefined);
const captchaVerifying = ref(false);
const captchaRef = useTemplateRef("captchaRef");
onMounted(() => {
fetch("https://mock.presstime.cn/mock/69d8c8165c2cd2d31df6900c/api/captcha")
.then((response) => response.json())
.then((response) => (captchaData.value = response?.data));
});
const verifyCaptcha = async (option: SliderCaptchaTrackItem) => {
captchaVerifying.value = true;
return fetch("https://mock.presstime.cn/mock/69d8c8165c2cd2d31df6900c/api/verify")
.then((response) => response.json())
.then((response) => response?.data?.passed)
.finally(() => (captchaVerifying.value = false));
};
const onVerifySuccess = () => {
alert("验证成功");
captchaRef.value?.reset();
};
</script>
<style>
.my-track {
border-radius: 20px;
}
.my-thumb {
border-radius: 20px;
background-color: #4caf50 !important;
color: #fff;
}
</style>浏览器兼容性
- Chrome/Edge (最新版本)
- Firefox (最新版本)
- Safari (最新版本)
- 移动端浏览器(支持触摸事件)
License
MIT
