使用Vue 实现滑动验证码功能(2)

<template> <div> <div :style="wrapperStyle"> <drop :class="{ 'over': state.over }" @dragover="onDragOver" @dragleave="onDragLeave" :style="targetStyle"> </drop> <drag :transfer-data="true" @dragstart="onDragStart" @dragend="onDragEnd" @drag="onDrag" v-if="!state.dragged" :style="sourceStyle"> <div slot="image" :style="sourceStyle"> </div> </drag> </div> </div> </template>

很清晰了,一个 <drop> 和一个 <drag> 组件,里面绑定了一些属性,下面对这两个组件的常用属性作一下说明。

Drop

对于 Drop 组件来说,它是一个被放置的对象,被拖动滑块会放到这个 Drop 滑块上,这就代表拖动成功了。它有两个主要的事件需要监听,一个叫做 dragover,一个叫做 dragleave,分别用来监听 Drag 对象拖上和拖开的事件。

在这里,分别对两个事件设置了 onDragOver 和 onDragLeave 的回调函数,当 Drag 对象放到 Drop 对象上面的时候,就会触发 onDragOver 对象,当拖开的时候就会触发 onDragLeave 事件。

那这样的话我们只需要一个全局变量来记录是否已经将滑块拖动到目标位置即可,比如可以定一个全局变量 state,我们用 over 属性来代表是否拖动到目标位置。

因此 onDragOver 和 onDragLeave 事件可以这么实现:

onDragOver() { this.state.over = true }, onDragLeave() { this.state.over = false }

Drag

对于 Drag 组件来说,它是一个被拖动的对象,我们需要将这个 Drag 滑块拖动到 Drop 滑块上,就代表拖动成功了。它有三个主要的时间需要监听:dragstart、drag、dragend,分别代表拖动开始、拖动中、拖动结束三个事件,我们这里也分别设置了三个回调方法 onDragStart、onDrag、onDragEnd。

对于 onDragStart 方法来说,应该怎么实现呢?这里应该处理刚拖动的一瞬间的动作,由于我们需要记录拖动的轨迹,所以声明一个 trace 全局变量来保存轨迹信息,onDragStart 要做的就是初始化 trace 对象为空,另外记录一下初始的拖动位置,以便后续计算拖动路径,所以可以实现如下:

onDragStart(data, event) { this.init = { x: event.offsetX, y: event.offsetY, } this.trace = [] }

对于 onDrag 方法来说,就是处理拖动过程中的一系列拖动动作,这里其实就是计算当前拖动的偏移位置,然后把它保存到 trace 变量里面,所以可以实现如下:

onDrag(data, event) { let offsetX = event.offsetX - this.init.x let offsetY = event.offsetY - this.init.y this.trace.push({ x: offsetX, y: offsetY, }) }

对于 onDragEnd 方法来说,其实就是检测最后的结果了,刚才我们用 state 变量里面的 over 属性来代表是否拖动到目标位置上,这里我们也定义了另外的 dragged 属性来代表是否已经拖动完成,dragging 属性来代表是否正在拖动,所以整个方法的逻辑上是检测 over 属性,然后对 dragging、dragged 属性做赋值,然后做一些相应的提示,实现如下:

onDragEnd() { if (this.state.over) { this.state.dragging = false this.state.dragged = true this.$message.success('拖动成功') } else { this.state.dragging = false this.state.dragged = false this.$message.error('拖动失败') } this.state.over = false }

OK 了,以上便是主要的逻辑实现,这样我们就可以完成拖动滑块的定义以及拖动的监听了。

接下来就是一些样式上的问题了,对于图片的呈现,这里直接使用 CSS 的 background-image 样式来设置的,如果想显示图片的某一个范围,那就用 background-position 来设置,这是几个核心的要点。

好,这里的样式设置其实也可以用 JavaScript 来实现,我们把它们定义为一些计算属性:

wrapperStyle() { return { width: this.size.width + 'px', height: this.size.height + 'px', backgroundImage: 'url(' + this.image + ')', backgroundSize: 'cover' } }, targetStyle() { return { left: this.block.x + 'px', top: this.block.y + 'px' } }, sourceStyle() { return { backgroundImage: 'url(' + this.image + ')', backgroundSize: this.size.width + 'px ' + this.size.height + 'px', backgroundPosition: -this.block.x + 'px ' + -this.block.y + 'px' } }

另外这里还有一个值得注意的地方,就是 Drag 组件的 slot 部分:

<div slot="image" :style="sourceStyle"></div>

这部分定义了在拖动过程中随鼠标移动的图片样式,这里也和 Drag 滑块一样定义了一样的样式,这样在拖动的过程中,就会显示一个和 Drag 滑块一样的滑块随鼠标移动。

最后,就是拖拽完成之后,将滑动轨迹输出出来,这里我就直接呈现在页面上了, <template> 区域加入如下定义即可:

<div> <p v-if="state.dragged"> 拖动轨迹:{{ trace }} </p> </div>

好,以上就是一些核心代码的介绍,还有一些细节的问题可以完善下,比如滑块随机初始化位置,以及拖动样式设置。

最后再看一遍效果:

使用Vue 实现滑动验证码功能


内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/e2a06f802f10a7ffab31720de264413e.html