SlideVerify
流畅的滑动验证组件。
简介
MSlideVerify 是一个滑动验证组件,提供拖拽交互与状态转换动画。基于 motion-v 实现流畅过渡,适用于表单验证、敏感操作确认等场景。
使用 Motion 动画库提供拖拽交互与状态转换动画
用法
按住滑块并向右拖动至阈值即可通过验证:
请向右滑动验证
<script setup lang="ts">
const value = ref(false)
</script>
<template>
<MSlideVerify v-model="value" />
</template>
threshold 通过阈值
threshold 决定拖动占比达到多少判定通过,默认 0.9,调低可放宽校验:
拖到一半即可
<template>
<MSlideVerify :threshold="0.5" text="拖到一半即可" />
</template>
text 提示文案
text 设定待验证提示,successText 设定通过后的文案:
按住并向右拖动
<template>
<MSlideVerify text="按住并向右拖动" success-text="人机校验已通过" />
</template>
icon 滑块图标
icon 设定待验证图标,successIcon 设定通过后的图标:
请向右滑动验证
<template>
<MSlideVerify icon="i-lucide-arrow-right" success-icon="i-lucide-shield-check" />
</template>
size 尺寸
通过 size 调整组件尺寸:
请向右滑动验证
<template>
<MSlideVerify size="md" />
</template>
disabled 禁用状态
disabled 冻结滑块,光标不可拖动且保持当前未验证态:
请向右滑动验证
<template>
<MSlideVerify disabled />
</template>
示例
继承字段上下文
放入 UFormField 后接收字段尺寸与错误态,滑块按表单状态渲染:
请向右滑动验证
示例错误态
<template>
<UFormField label="滑动验证" size="xs" error="示例错误态">
<MSlideVerify />
</UFormField>
</template>
融入UFieldGroup
与重置按钮组合时共享 UFieldGroup 尺寸,滑块区域和按钮保持统一高度:
请向右滑动验证
<template>
<UFieldGroup size="xs">
<MSlideVerify class="flex-1" />
<UButton icon="i-lucide-rotate-ccw" color="neutral" variant="subtle" />
</UFieldGroup>
</template>
自定义滑块内容
slider 插槽接管滑块内部渲染,可读取 verified 与 progress 动态展示进度:
请向右滑动验证
0%
<script setup lang="ts">
const isVerified = ref(false)
</script>
<template>
<MSlideVerify v-model="isVerified" class="w-sm">
<template #slider="{ verified, progress }">
<UIcon v-if="verified" name="i-lucide-check" />
<span v-else class="text-xs font-medium">{{ Math.round(progress * 100) }}%</span>
</template>
</MSlideVerify>
</template>
事件回调
开始拖动触发 dragStart,松手触发 dragEnd 并回传是否成功,达到阈值额外触发 success:
请向右滑动验证
<script setup lang="ts">
const isVerified = ref(false)
const slideVerifyRef = useTemplateRef('slideVerifyRef')
const toast = useToast()
function handleSuccess() {
toast.add({
title: '验证成功',
description: '已触发 success 事件',
color: 'success'
})
}
function handleDragEnd(success: boolean) {
if (!success) {
toast.add({
title: '验证失败',
description: '请继续滑动',
color: 'neutral'
})
}
}
function handleReset() {
slideVerifyRef.value?.reset()
toast.add({
title: '已重置',
color: 'neutral'
})
}
</script>
<template>
<div class="w-sm flex gap-4">
<MSlideVerify
ref="slideVerifyRef"
v-model="isVerified"
class="flex-1"
@success="handleSuccess"
@drag-end="handleDragEnd"
/>
<UButton size="sm" color="neutral" variant="outline" @click="handleReset"> 重置验证 </UButton>
</div>
</template>
API
Props
| Prop | Default | Type |
|---|---|---|
text | '请向右滑动验证' | string待滑动时的提示文本 |
icon | 'i-lucide-chevrons-right' | any滑块图标 |
successText | '验证成功' | string验证成功时的提示文本 |
successIcon | 'i-lucide-check' | any验证成功时的图标 |
threshold | 0.9 | number完成验证所需的阈值百分比(0-1) |
size | 'md' | "md" | "xs" | "sm" | "lg" | "xl"尺寸大小 |
id | string | |
name | string | |
disabled | boolean是否禁用 | |
modelValue | false | boolean |
ui | Record<string, ClassNameValue> & { root?: SlotClass; track?: SlotClass; fill?: SlotClass; text?: SlotClass; slider?: SlotClass; icon?: SlotClass; } |
Emits
| Event | Type |
|---|---|
update:modelValue | [value: boolean] |
success | [] |
dragStart | [] |
dragEnd | [success: boolean] |
Slots
| Slot | Type |
|---|---|
slider | { verified?: boolean; progress: number; } |
Expose
您可以通过 useTemplateRef 访问该类型化组件实例。
| Name | Type |
|---|---|
reset() | Promise<void> 重置验证状态 |
Theme
app.config.ts
export default defineAppConfig({
ui: {
slideVerify: {
slots: {
root: 'w-full relative flex items-center select-none overflow-hidden rounded-md border transition-colors duration-300',
track: 'absolute inset-0',
fill: 'absolute inset-y-0 left-0 bg-primary/20 opacity-60',
text: 'absolute inset-0 flex items-center justify-center font-medium pointer-events-none',
slider: 'relative z-10 flex shrink-0 touch-none items-center justify-center rounded-md shadow-sm transition-colors',
icon: 'shrink-0'
},
variants: {
size: {
xs: {
root: 'p-1',
text: 'text-xs',
slider: 'px-2 py-1',
icon: 'size-4'
},
sm: {
root: 'p-1.5',
text: 'text-xs',
slider: 'px-2.5 py-1.5',
icon: 'size-4'
},
md: {
root: 'p-1.5',
text: 'text-sm',
slider: 'px-2.5 py-1.5',
icon: 'size-5'
},
lg: {
root: 'p-2',
text: 'text-sm',
slider: 'px-3 py-2',
icon: 'size-5'
},
xl: {
root: 'p-2',
text: 'text-base',
slider: 'px-3 py-2',
icon: 'size-6'
}
},
disabled: {
true: {
root: 'opacity-50 cursor-not-allowed'
}
},
verified: {
true: {
root: 'bg-success border-transparent',
slider: 'bg-white/90',
icon: 'text-success'
},
false: {
root: 'bg-elevated border-default',
slider: 'bg-default cursor-grab active:cursor-grabbing ring-1 ring-default',
icon: 'text-primary'
}
},
fieldGroup: {
horizontal: {
root: 'not-only:first:rounded-e-none not-only:last:rounded-s-none not-last:not-first:rounded-none focus-visible:z-[1]'
},
vertical: {
root: 'not-only:first:rounded-b-none not-only:last:rounded-t-none not-last:not-first:rounded-none focus-visible:z-[1]'
}
}
},
defaultVariants: {
size: 'md'
}
}
}
})
Changelog
No recent changes