Vue3+Vite实训:图片滑块验证

Vue3+Vite实训:图片滑块验证

创建项目

  • 使用Vite创建项目:npm create cite my-app

  • 选择vue框架

  • 全局安装yarn:npm install -g yarn

  • yarn安装依赖

  • 运行:yarn dev

ImgCheck.Vue

完成基本样式

  • 在components创建ImgCheck.Vue

  • 在template中写入页面样式

  • 导入两张图片:大图及拼块图

  • 创建蓝色滑动方块

  • 写css 对整个界面进行润色

完成实现功能

  • 在setup拿到关键信息

  • 引入reactive 声明data 声明初始位置

  • 声明props 传递top 设置类型和默认值 运用.语法可以访问top 在APP.Vue可以let一个top 使服务端随着图片生成的

  • 绑定滑块事件 实现整个滑动验证流程

  • btnMouseDown:鼠标按下 绑定给方块

  • 添加事件mousemove 执行事件为btnMouseMove 使按下才开始计算滑动

  • 计算出鼠标按下的位置-btn距离窗口的位置=鼠标位置距离btn的边距

  • 引用btnref为鼠标位置距离btn的边距 在data中初始为null 在btn中ref值为btnref

  • 用const将btnref解构为data对象 可以直接得到btnref 可以直接用offset...得到具体属性

  • data.btnleft=e.pageX - data.btnref.offsetLeft;

  • btnMouseMove:按着移动 滑动时只要求鼠标没松开 绑定给border-使用生命周期onMounted

  • 按下 才计算滑动

  • 拿到位置 让data.left等于位置

  • 让btn插入一样的style便可一起和拼块图滑动

  • 在onMounted就应该能偶取得data.btnref.offsetLeft 否则会产生回弹 在data初始ImgRef为0 绑定在大图盒子里 并解构出来 onMouted拿到的便是data.btnleft=ImgRef的left属性

  • 在btnMouseMove中就是x = e.pageX - data.offsetLeft - data.btnleft 这也就不会产生回弹

  • btnMouseUp:鼠标松开 绑定给方块

  • 移除事件 mousemove 松开 停止计算滑动

  • 让控制台显示松开位置 注意取值的边界判断

ImgCheck.Vue代码

<template>
    
    <div class="box">
        <h3>拖动下方滑块完成拼图</h3>
        <div ref="bgImgref" class="img-box">
            <img class="bg" src="../assets/hycdn.jpeg" alt="">
            <img class="hd"
             src="../assets/hycdn.png"
             :style="{left:data.left+'px' ,top:data.top+'px'}"
             alt="">
        </div>
        <div class="btn-box">
            <div
            ref="btnref" 
            class="btn"
            :style="{left:data.left+'px' }"
            @mousedown="btnMouseDown"
            @mouseup="btnMouseUp"
            >|||</div>
        </div>
    </div>
</template>

<script setup>
import { reactive,onMounted,toRefs } from 'vue';

let $props=defineProps({
    top:{
        type:Number,
        default:45,
    }

});

let $emit = defineEmits(['getPosition'])

const data = reactive({
    left:28,
    top:$props.top,
    btnleft:0,
    btnref:null,
    offsetLeft:0,
    bgImgref:null
});
const{ btnref,bgImgref } = toRefs(data);

onMounted(()=>{
    data.offsetLeft = data.bgImgref.offsetLeft;
   console.log("onMounted");
   document.body.addEventListener("mouseup",btnMouseUp);
})

var btnMouseDown=(e)=>{
    // console.log(e);
    //计算出鼠标按下位置 pagex-btn距离窗口的位置=鼠标位置距离btn的边距
    data.btnleft=e.pageX - data.btnref.offsetLeft;
    document.body.addEventListener("mousemove",btnMouseMove);
}

//滑动时只要求鼠标不松开
var btnMouseMove=(e)=>{
    // console.log("滑动");
    //left=pageX - data.btnref.offsetLeft
    let x = e.pageX - data.offsetLeft - data.btnleft
    if(x<=0)x=0
    else if(x>=285)x=285
    data.left = x;
}

var btnMouseUp=(e)=>{
    //console.log(data.left);
    $emit("getPosition",data.left)
    document.body.removeEventListener("mousemove",btnMouseMove)
};
</script>

<style scoped>
html,
body {
  width: 100%;
  height: 100%;
  user-select: none;
}
.box {
  width: 340px;
  height: 300px;
  border: 1px solid #ccc;
  margin: 0 auto;
  padding: 10px;
}
.img-box {
  position: relative;
}
.bg {
  width: 100%;
}
.hd {
  position: absolute;
  height: 68px;
  width: 68px;
  /* top: 45px; */
  left: 26px;
  cursor: pointer;
}
.btn-box {
  width: 100%;
  height: 10px;
  border-radius: 5px;
  background: #e4e4e4;
  margin-top: 15px;
}
.btn {
  position: relative;
  top: -10px;
  left: 26px;
  width: 55px;
  height: 30px;
  text-align: center;
  letter-spacing: 5px;
  line-height: 30px;
  color: #fff;
  border-radius: 15px;
  background-color: rgb(26, 121, 255);
  box-shadow: rgb(26 121 255 / 52%) 0px 0px 10px 1px;
  cursor: pointer;
}
</style>

App.Vue

  • left的值给到服务端 在script中写getPosition得到x值 弹窗“成功”

  • 在ImgCheck的div中注册事件getPosition

  • 在App.Vue利用emit标记一个只可读对象得到getPosition

  • 在松开事件中用emit促发getPosition得到的是data.left

App.Vue代码

<script setup>
// import HelloWorld from './components/HelloWorld.vue'
import ImgCheck from './components/imgCheck.vue' 
let top = 45;

const getPosition = (x)=>{
  console.log(x,"http");
  if(x>=225&&x<=250){
    window.alert("成功!");
  }
}
</script>

<template>
  <!-- <div>
    <a href="https://vitejs.dev" target="_blank">
      <img src="/vite.svg" class="logo" alt="Vite logo" />
    </a>
    <a href="https://vuejs.org/" target="_blank">
      <img src="./assets/vue.svg" class="logo vue" alt="Vue logo" />
    </a>
  </div> -->
  <!-- <HelloWorld msg="Vite + Vue" /> -->
  
  
  <div><ImgCheck @getPosition= "getPosition" :top="top"  /></div>
</template>

<style scoped>
.logo {
  height: 6em;
  padding: 1.5em;
  will-change: filter;
  transition: filter 300ms;
}
.logo:hover {
  filter: drop-shadow(0 0 2em #646cffaa);
}
.logo.vue:hover {
  filter: drop-shadow(0 0 2em #42b883aa);
}
</style>

运行效果

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值