PuzzleVerify 滑块拼图验证 
温馨提示
组件内部使用了 fui-icon(字体图标)组件,非 easycom 组件模式下需要手动引入组件(打开组件内部注释的引入内容,引入路径按实际调整)。
此组件需结合后端进行验证,需要在后端生成裁剪背景图以及裁剪下的图片返回给前端。
裁剪区域宽高固定为 44(px)。
# 支持平台
| App-vue | App-Nvue | 微信小程序 | 支付宝小程序 | 百度小程序 | 字节小程序 | QQ小程序 | H5 | PC | 快手小程序 | 钉钉小程序 |
|---|---|---|---|---|---|---|---|---|---|---|
| ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
# 引入
以下介绍两种常用的引入方式。
第一种:在页面中引用、注册
import fuiPuzzleVerify from "@/components/firstui/fui-puzzle-verify/fui-puzzle-verify.vue"
export default {
components:{
fuiPuzzleVerify
}
}
1
2
3
4
5
6
2
3
4
5
6
第二种:easycom组件规范
传统vue组件,需要安装、引用、注册,三个步骤后才能使用组件。easycom将其精简为一步。
First UI easycom配置请查看 快速上手。
如果不了解easycom,可先查看 官网文档 (opens new window)。
# 代码演示
部分示例演示,完整使用请参考示例程序以及文档API。
基础使用
通过 width 属性设置验证背景图宽度,height 属性设置验证背景图高度,src 属性设置验证背景图,cutSrc 属性设置裁剪图片,x 属性设置裁剪图片在背景图内的left值,y 属性设置裁剪图片在背景图内的top值。
通过 ref 属性来注册组件引用信息。注册完成后,我们可以通过this.$refs.XXX访问到对应的组件实例,并调用上面的实例方法。
<fui-puzzle-verify :width="width" :height="height" :src="src" :cutSrc="cutSrc" :x="40" :y="49" @init="init" @verify="verify" ref="pvRef"></fui-puzzle-verify>
1
export default {
data() {
return {
resUrl: this.fui.resUrl(),
src: '',
cutSrc: '',
width: 300,
height: 150,
x: 0,
y: 0
}
},
methods: {
//rpx转化为px
getPx(value) {
let val = parseInt(uni.upx2px(Number(value)))
return val % 2 === 0 ? val : val + 1
},
//初始化事件中请求接口获取 有黑块的背景图、裁剪图、位置等信息
//画布大小可使用rpx转化为px传回给后端使用,动态生成背景图,这样可做到自适应,适配所有终端
//示例使用的是已生成好的图,所以使用的是固定宽高
init(e) {
//裁剪图片宽度,固定为44(px)
let cutGraphWidth = e.cutGraphWidth
this.width = 300 //this.getPx(640)
this.height = 150 //this.getPx(320)
//以上参数传给后端获取验证信息
//示例仅为演示,使用预处理内容
this.getVerifyImage()
},
//注意:为了避免图片显示失真,后端处理图片大小需按照提供的参数等比放大倍数,可根据设备pixelRatio(设备像素比)等比放大
getVerifyImage() {
//以下由后端获取返回(x1:裁剪位置由后端存储,不返回)
//带黑块的背景图,后端接口提供
this.src = `${this.resUrl}/component/sc/bg_img_verify.png`
//裁剪下的图片,后端接口提供
this.cutSrc = `${this.resUrl}/component/sc/cut_img.png`
//裁剪图在背景图内的left值 ,后端接口提供
this.x = 40;
//裁剪图在背景图内的top值 ,后端接口提供
this.y = 49
},
//触发显示拼图验证组件
btnVerify() {
//需要等组件初始化完成
this.$refs.pvRef && this.$refs.pvRef.show()
},
//开始验证,将返回的滑动距离传给后端进行验证
verify(e) {
//示例仅为演示,以下为模拟后端验证
//滑动距离
let slipDistance = e.slipDistance
//验证方法,参考js方法自行转为后端方法
//x1为裁剪黑块的left值,该值仅后端知道,示例使用的预处理数据,此处仅为演示
let x1 = 222;
//width为需要滑动的总距离
let width = x1 - this.x
//误差范围,后端自行定义(px)
let range = 3
//滑动距离 减去 总距离 的绝对值 小于等于误差范围即为验证通过
if (Math.abs(slipDistance - width) <= range) {
this.success()
} else {
this.fui.toast('验证失败!')
//重置验证
this.$refs.pvRef.reset()
//当失败多次时,可重新生成验证数据返回
//...
}
},
success() {
this.fui.toast('验证通过!')
setTimeout(() => {
//关闭验证框
this.$refs.pvRef.closeVerify()
}, 200)
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# Slots
| 插槽名称 | 说明 |
|---|---|
| - | - |
# Props
| 属性名 | 类型 | 说明 | 默认值 | 平台差异说明 |
|---|---|---|---|---|
| src | String | 含裁剪黑块的背景图片地址,必选参数。 | - | - |
| cutSrc | String | 裁剪下的图片地址,必选参数。 | - | - |
| x | Number, String | 裁剪图在背景图内的left值,单位px,必选参数。 | 10 | - |
| y | Number, String | 裁剪图在背景图内的top值,单位px,必选参数。 | 10 | - |
| width | Number, String | 背景图片宽度,单位px | 300 | - |
| height | Number, String | 背景图片高度,单位px | 150 | - |
| background | String | 验证弹层背景颜色 | #FFFFFF | - |
| title | String | 验证弹层标题。请限制字数,避免过长 | 安全验证 | - |
| color | String | 标题字体颜色 | #B2B2B2 | - |
| size | Number, String | 标题字体大小,单位rpx | 28 | - |
| descrColor | String | 验证提示字体颜色 | #333333 | - |
| closeColor | String | 关闭图标颜色 | #B2B2B2 | - |
| sliderBgColor | String | 滑块的背景颜色 | #465CFF | 非Nvue端默认为空,可通过css变量(--fui-color-primary)来修改颜色值 |
| slideColor | String | 滑动图标颜色(滑块内部图标) | #FFFFFF | - |
| zIndex | Number, String | 验证弹层层级z-index值 | 996 | - |
| maskBgColor | String | 遮罩背景色 | rgba(0,0,0,.6) | - |
| maskClosable | Boolean | 点击遮罩是否可关闭验证弹框 | false | - |
//注:裁剪图片尺寸默认宽高44px。
//画布大小(width、height)可使用rpx转化为px传回给后端使用,动态生成背景图,这样可做到自适应,适配所有终端
//特别说明:
//x、x1(裁剪位置left值)、y应该均为在一定范围内随机产生,请参考js方法,自行转为后端方法:
getRandom(min, max) {
let range = Array.from(new Array(max + 1).keys()).slice(min);
let index = Math.floor((Math.random() * range.length));
return range[index]
},
//this.width 背景图片宽度,单位px、this.height 背景图片高度,单位px
//其中 44 为裁剪图片的宽高值,固定值,单位px
getXY() {
// x大于等于20,小于等于宽度的一半减去44
this.x = this.getRandom(20, this.width / 2 - 44)
// y大于等于20,小于等于高度减去60(减去的值大于等于44即可)
this.y = this.getRandom(20, this.height - 60)
// x1大于宽度一半加上44,宽度减去60(减去的值大于等于44即可)
this.x1 = this.getRandom(this.width / 2 + 44, this.width - 60)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Events
注:以下所有回调参数涉及单位的均为px
| 事件名 | 说明 | 回调参数 |
|---|---|---|
| @init | 初始化时触发 | { cutGraphWidth : 裁剪图片的宽高 } |
| @verify | 开始验证,滑动结束后触发 | { slipDistance : 滑动的距离 } |
//特别说明:
先通过 @init 事件获取到相应参数,然后请求后端接口获取位置信息以及背景图片、裁剪下的图片。
@verify 事件返回用户操作后滑动的距离,传给后端进行验证。
//验证方法,参考js方法自行转为后端方法
//x1为裁剪黑块的left值,该值仅后端保存
let x1 = 222;
//width为需要滑动的总距离
let width = x1 - this.x
//误差范围,后端自行定义(px)
let range = 3
//滑动距离 减去 总距离 的绝对值 小于等于误差范围即为验证通过
if (Math.abs(slipDistance - width) <= range) {
this.fui.toast('验证通过!')
} else {
this.fui.toast('验证失败!')
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# Methods
通过 ref 属性来注册组件引用信息。注册完成后,我们可以通过this.$refs.XXX访问到对应的组件实例,并调用上面的实例方法。
| 方法名 | 说明 | 传入参数 | 返回参数 |
|---|---|---|---|
| show | 打开验证框 | - | - |
| closeVerify | 关闭验证框并重置验证 | - | - |
| reset | 重置验证 | - | - |