<template> <el-dialog :visible.sync="dialogVisible" custom-class="slideVerifyDialog" :close-on-click-modal="false" title="身份验证" width="360px" > <section class="slider-section"> <div class="img-box"> <img :src="bigImgSrc" class="bg-img" ref="bgImg" /> <img :src="sliderImgSrc" class="slider-img" ref="sliderImg" /> <i class="refresh-btn el-icon-refresh" @click="init" /> </div> <div class="slider-box"> <span class="slider-text">向右滑动滑块填充拼图</span> <div class="slider-icon" @mousedown="rangeMove">></div> </div> </section> </el-dialog> </template> <script lang="ts"> import { Vue, Component, Prop, Ref } from 'vue-property-decorator' import { getSlideImg, checkSlide } from '@/modules/login/api/login' @Component({ name: 'SlideVerifyDialog' }) export default class SlideVerifyDialog extends Vue { @Prop() visible!: boolean @Ref() bgImg: any @Ref() sliderImg: any bigImgSrc = '' sliderImgSrc = '' disX = 0 // 滑块距离背景图左侧的位置 slide: any = { bigHeight: 0, bigImageBase64: '', bigWidth: 0, code: '', posX: 0, posY: 0, smallHeight: 0, smallImageBase64: '', smallWidth: 0 } get dialogVisible() { return this.visible } set dialogVisible(val: boolean) { this.$emit('update:visible', val) } mounted() { this.init() } getSide() {
// 这是获取滑块code的 return getSlideImg().then((res: any) => { this.slide = res.data }) } checkSlide() {
// 这里把滑块的code和滑块x轴滑动的距离传给后端 checkSlide({ code: this.slide.code, posX: this.disX }) .then(() => { this.dialogVisible = false this.$emit('submitPic', { code: this.slide.code, posX: this.disX }) }) .catch(() => { this.init() }) } async init() { await this.getSide() this.disX = 0 // 初始化滑块位置 this.bigImgSrc = 'data:image/png;base64,' + this.slide.bigImageBase64 this.sliderImgSrc = 'data:image/png;base64,' + this.slide.smallImageBase64 this.sliderImg.style.width = this.slide.smallWidth + 'px' // 设置滑块图片宽度 this.sliderImg.style.height = this.slide.smallHeight + 'px' // 设置滑块图片高度 this.sliderImg.style.top = `${Number(this.slide.posY) + 1}px` // 设置滑块距离背景图顶部的距离 this.sliderImg.style.left = 0 // 设置滑块距离背景图左侧的距离 } // 移动事件触发 rangeMove(e: any) { const ele = e.target const startX = e.clientX const eleWidth = ele.offsetWidth const parentWidth = ele.parentElement.offsetWidth const MaxX = parentWidth - eleWidth document.onmousemove = (event: any) => { const endX = event.clientX this.disX = endX - startX this.sliderImg.style.left = this.disX + 'px' if (this.disX <= 0) { this.disX = 0 this.sliderImg.style.left = 0 } if (this.disX >= MaxX - eleWidth) { // 减去滑块的宽度,体验效果更好 this.disX = MaxX this.sliderImg.style.left = parentWidth - this.sliderImg.width + 'px' } ele.style.transition = '.1s all' ele.style.transform = 'translateX(' + this.disX + 'px)' event.preventDefault() } document.onmouseup = () => { this.checkSlide() // this.$emit('submitPic', { code: this.slide.code, posX: this.disX }); setTimeout(() => { ele.style.transition = '.1s all' // 初始化滑块位置 ele.style.transform = 'translateX(0)' }, 200) document.onmousemove = null document.onmouseup = null } } } </script> <style lang="scss" scoped> .slideVerifyDialog { margin: 0 !important; position: absolute !important; top: 50% !important; left: 50% !important; transform: translate(-50%, -50%) !important; .el-dialog__body { padding: 16px !important; } } </style> <style scoped lang="scss"> .slider-section { // margin: 20px 0; .img-box { position: relative; .bg-img { width: 100%; } .refresh-btn { position: absolute; cursor: pointer; bottom: 16px; right: 16px; width: 20px; height: 20px; font-size: 20px !important; color: #fff; z-index: 20; } .slider-img { position: absolute; left: 0; top: 0; z-index: 30; } } .slider-box { margin-top: 20px; background: #f7f9fa; color: #666; border: 1px solid #e4e7eb; position: relative; height: 30px; width: 100%; &:hover { box-shadow: 0 0 3px #ccc; } .slider-text { font-size: 14px; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); } .slider-icon { cursor: move; width: 30px; height: 30px; line-height: 30px; background: #c8923a; text-align: center; font-size: 20px !important; color: #fff; box-shadow: 0 0 6px #ccc; } } } </style>
效果
标签:style,vue,滑块,disX,slide,code,前端开发,important From: https://www.cnblogs.com/xiaohuizhang/p/17175873.html