不多逼逼,懂得都懂,直接上代码!!
以下是子组件的代码
<template>
<div class="slider_box">
<div class="verification">
<span class="verification-span">请完成安全验证</span>
<i class="el-icon-close" @click="offVerify"></i>
<hr class="line" />
</div>
<div class="slide_img_content">
<div class="slide_img">
<img
class="slide_refresh"
src="../../../static/login/icon/refresh.png"
@click="uploadSlideVerificationCode();"
/>
<img id="cutImage" class="slide_img_mark" ref="cutImage" />
<img id="originalImage" ref="originalImage" />
</div>
</div>
<div class="slider_clear">
<div class="slider">
<div
class="slider_arror"
ref="slider_arror"
style="cursor:pointer;"
onselectstart="return false;"
>
<img
style="margin-top: 5px;"
id="arror_icon"
src="../../../static/login/icon/right_arror.png"
draggable="false"
width="30px"
height="30px"
ref="arror_icon"
/>
</div>
<div class="slider_mask" ref="slider_mask"></div>
<span class="slider_tip" onselectstart="return false;" ref="slider_tip">向右拖动滑块填充拼图</span>
</div>
</div>
<p
id="slideVerificationCodeError"
style="font-weight:bold"
ref="slideVerificationCodeError"
></p>
</div>
</template>
<script>
import {
slideVerificationCode,
checkSlideVerificationSlideX,
} from "@/api/user.js"; //这两个接口也是看你的项目怎么来,我就是为了保存代码完整性留下来的
export default {
name: "slider",
data() {
return {
success: true,
successVerifyTime: null,
uploadSlideVerificationCodeTime: null,
sliderStart: false,
x_slider: null,// 鼠标最初位置
y_slider: null,// 鼠标最初位置
original_image_with_slider: 300,//边界宽度 = 图片宽度
cut_image_width_slider: 50,//剪切图宽度
yLocation: null,// 数据返回 x y
//图片显示使用base64时的前缀,src=base64PrefixPathSlide + imgBase64Value
base64PrefixPathSlide: "data:image/png;base64,",
}
},
created() {
},
methods: {
offVerify() {
this.$emit("offMask")
},
uploadSlideVerificationCode() {
this.resetSlide(); //拼图验证码用---修改位置和重置颜色
slideVerificationCode().then(jsonData => {
if (jsonData.data.code == 0) {
var data = JSON.parse(jsonData.data.data);
this.yLocation = data.yLocation;
this.initImgSlide(data.originalImage, data.cutImage, this.yLocation);
this.initMovementSlide();
this.$refs.slideVerificationCodeError.innerText = ""
}
});
},
//图片显示使用base64时的前缀,src=base64PrefixPathSlide + imgBase64Value
// var base64PrefixPathSlide = "data:image/png;base64,";
// 拼图验证码用---初始化图片
initImgSlide(originalImage, cutImage, yLocation) {
this.$refs.originalImage.src = this.base64PrefixPathSlide + originalImage
this.$refs.cutImage.src = this.base64PrefixPathSlide + cutImage
this.$refs.cutImage.style.marginTop = yLocation + 'px'
},
// 拼图验证码用---设置回调
initMovementSlide() {
this.$refs.arror_icon.addEventListener("mousedown", this.sliderPush);
document.addEventListener("mousemove", this.sliderDrug);
document.addEventListener("mouseup", this.sliderEnd);
},
// 拼图验证码用---按下滑动按钮回调方法
sliderPush(e) {
this.sliderStart = true;
this.x_slider = e.clientX || e.touches[0].clientX;
this.y_slider = e.clientY || e.touches[0].clientY;
this.$refs.slider_tip.style.display = "none"
this.$refs.slider_mask.style.backgroundColor = "#deee97"
this.$refs.arror_icon.src = "../../../static/login/icon/right_arror.png"
},
// 拼图验证码用---开始滑动回调方法, 改变arror位置和mask大小
sliderDrug(e) {
if (!this.sliderStart) return false;
// 获取鼠标移动位置
var eventX = e.clientX || e.touches[0].clientX;
var eventY = e.clientY || e.touches[0].clientY;
var moveX = eventX - this.x_slider;
var moveY = eventY - this.y_slider;
// 确保边界
if (
moveX < 0 ||
moveX + parseInt(this.cut_image_width_slider) > this.original_image_with_slider
) {
return false;
}
// 改变slider_arror的位置和mask大小
this.$refs.slider_arror.style.marginLeft = moveX + "px"
this.$refs.slider_arror.style.cursor = "pointer"
this.$refs.slider_mask.style.width = moveX + "px"
this.$refs.cutImage.style.marginLeft = moveX + "px"
},
// 拼图验证码用---结束时进行判断回调方法
sliderEnd(e) {
if (!this.sliderStart) return false;
this.sliderStart = false;
const slideImgMark = document.getElementById("cutImage")
var slideX = slideImgMark.style.marginLeft
slideX = slideX.toString().slice(0, -2);
var tip = this.$refs.slideVerificationCodeError
checkSlideVerificationSlideX(slideX).then(jsonData => {
if (jsonData.data.code == 0) {
var data = jsonData.data.data;
if (data == "true") {
tip.color = "green"
tip.innerText = "恭喜你,滑动验证码正确";
this.successSlide();
}
else if (data == "false") {
tip.color = "red";
tip.innerText = "滑动验证码错误,请重新滑动";
this.failedSlide();
} else {
tip.color = "red";
tip.innerText = "滑动验证码过期,请重新滑动";
this.failedSlide();
}
}
})
},
// 拼图验证码用---验证成功回调方法
successSlide() {
this.$refs.arror_icon.src = "../../../static/login/icon/green_correct.png"
this.$refs.slider_mask.style.backgroundColor = "#79e77e"
//移除一系列鼠标事件
this.$refs.arror_icon.removeEventListener("mousedown", this.sliderPush);
document.removeEventListener("mousemove", this.sliderDrug);
document.removeEventListener("mouseup", this.sliderEnd);
//验证成功后隐藏验证框
clearTimeout(this.successVerifyTime)
this.successVerifyTime = null
this.successVerifyTime = setTimeout(() => {
this.$emit("successVerify", this.success);
}, 500);
},
// 拼图验证码用---失败重置
failedSlide() {
this.$refs.arror_icon.src = "../../../static/login/icon/red_error.png"
this.$refs.slider_mask.style.backgroundColor = "#e73c4a"
clearTimeout(this.uploadSlideVerificationCodeTime)
this.uploadSlideVerificationCodeTime = null
this.uploadSlideVerificationCodeTime = setTimeout(this.uploadSlideVerificationCode, 1000);
},
// 拼图验证码用---修改位置和重置颜色
resetSlide() {
this.$refs.slider_mask.style.backgroundColor = "#deee97"
this.$refs.slider_arror.style.marginLeft = 0
this.$refs.slider_arror.style.cursor = "pointer"
this.$refs.slider_mask.style.width = 0
const slideImgMark = document.getElementById("cutImage")
slideImgMark.style.marginLeft = 0;
this.$refs.arror_icon.src = "../../../static/login/icon/right_arror.png"
this.$refs.slider_tip.style.display = "block"
this.$refs.slideVerificationCodeError.innerText = ""
}
}
}
</script>
<style lang="scss" >
.verification {
margin-bottom: 10px;
.verification-span {
padding: 5px;
}
.el-icon-close {
float: right;
margin: 5px;
}
.line {
position: absolute;
top: 32px;
left: 0;
width: 320px;
}
}
.slide_img_content {
position: relative;
margin: auto;
}
.slide_img {
width: 300px;
height: 200px;
position: relative;
}
.slide_img_mark {
position: absolute;
height: 50px;
width: 50px;
margin-top: 50px;
margin-left: 0;
}
.slider {
float: left;
margin: 10px auto auto;
height: 40px;
width: 300px;
border: 1px solid #c6cbd1;
background-color: #f9fbfc;
}
.slider_arror {
position: absolute;
margin-left: 0;
height: 40px;
width: 50px;
border-left: 1px solid #252627;
border-right: 1px solid #252627;
text-align: center;
}
.slider_arror:hover {
background-color: #deee97;
}
.slider_mask {
position: absolute;
margin-left: 0;
margin-top: 0;
width: 0;
height: 40px;
background-color: #deee97;
}
.slider_tip {
position: absolute;
margin-left: 95px;
margin-top: 3px;
}
.slider_clear:after {
/*伪元素是行内元素 正常浏览器清除浮动方法*/
content: '';
display: block;
height: 0;
clear: both;
visibility: hidden;
}
.slider_clear {
*zoom: 1; /*ie6清除浮动的方式 *号只有IE6-IE7执行,其他浏览器不执行*/
}
.slide_refresh {
width: 30px;
height: 30px;
position: absolute;
top: 10px;
right: 10px;
cursor: pointer;
}
</style>
以下是父组件代码
<template>
<!-- 图片右滑验证 -->
<div class="slideContainer_max" ref="slideContainer_max" v-show="isShowSlide">
<div class="mask" v-show="isShowSlide" ref="mask"></div>
<div class="slideContainer" v-show="isShowSlide" ref="slideContainer">
<slider
v-show="isShowSlide"
@offMask="offMask"
@successVerify="successVerify"
ref="sliderChild"
></slider>
</div>
</div>
</template>
<script>
export default {
name: 'userlogin',
components: {
slider
},
data(){
return {
isShowSlide: false,
}
},
methods:{
//这个函数就是触发验证图片弹出来的,可以绑定给你想要触发的某个按钮
refreshCode() {
this.successVerify()
},
//验证成功或者手动时,关闭遮罩层
offMask() {
this.isShowSlide = false
},
//右滑验证成功或者不成功逻辑
successVerify(msg) {
if (msg) {
this.isShowSlide = false
this.resetCode()
}
else {
this.isShowSlide = true
this.$refs.sliderChild.uploadSlideVerificationCode()
}
},
//刷新验证码
resetCode() {
//这个验证码刷新具体看你项目的需要格式
},
}
<style lang="scss">
.mask {
position: fixed;
left: 0%;
top: 0%;
width: 100%;
height: 100%;
z-index: 499;
overflow: hidden;
background-color: rgba(218, 238, 255, 0.9);
}
.slideContainer {
background: #fff;
padding: 10px;
position: fixed;
left: 60%;
top: 21%;
z-index: 999;
}
</style>