vue实现盒子内拖动方块移动的示例代码
作者:russo_zhang
这篇文章主要给大家介绍了如何通过vue实现盒子内拖动方块移动,文章通过代码示例讲解的非常详细,具有一定的参考价值,感兴趣的小伙伴可以参考阅读本文
vue实现盒子内拖动方块移动
本文采用vue2的options api。
1. 创建盒子与方块
最简单的父子嵌套盒子,子盒子绝对定位。
<template> <div class="Drag"> <div class="scroll_thumb"></div> </div> </template> <script> export default { name: "Drag", }; </script> <style scoped> .Drag { position: relative; width: 1000px; height: 600px; border: 1px solid #333; margin: 100px auto; } .Drag .scroll_thumb { position: absolute; top: 0; left: 0; width: 20px; height: 20px; background-color: gold; } </style>
2.获取父盒子在文档的位置信息
使用getBoundingClientRect API获取
<template> <div ref="drag" class="Drag"> <div class="scroll_thumb"></div> </div> </template> <script> export default { name: "Drag", data() { return { boxRect: {}, //父盒子位置信息 }; }, mounted() { this.setBoxRect(); // 窗口变化时重新获取数据 window.addEventListener("resize", this.setBoxRect); }, beforeDestroy() { window.removeEventListener("resize", this.setBoxRect); }, methods: { setBoxRect() { //获取父盒子在文档的位置信息 this.boxRect = this.$refs.drag.getBoundingClientRect(); }, }, } </script>
3.监听鼠标点击事件
<template> <div ref="drag" class="Drag"> <div class="scroll_thumb" @mousedown="mousedown"></div> </div> </template> <script> export default { methods: { // 点击鼠标按键触发 mousedown() { // 判断是否是鼠标左键 if (event.button !== 0) return; // 监听鼠标移动与弹起事件 document.addEventListener("mousemove", this.mousemove); document.addEventListener("mouseup", this.mouseup); }, // 鼠标移动触发 mousemove(event) { // 此为关键代码,下面进行分析 }, // 鼠标按键弹起时移除监听的时间 mouseup() { this.removeMouseEvent() }, removeMouseEvent() { document.removeEventListener("mousemove", this.mousemove); document.removeEventListener("mouseup", this.mouseup); }, }, }; </script>
4.计算方块跟随鼠标移动
<template> <div ref="drag" class="Drag"> <!-- 动态计算方块的top与left --> <div class="scroll_thumb" :style="{ width: `${thumbW}px`, height: `${thumbH}px`, top: `${thumbTop}px`, left: `${thumbLeft}px`, }" @mousedown="mousedown" ></div> </div> </template> <script> export default { name: "Drag", data() { return { // 方块的位置 thumbTop: 0, thumbLeft: 0, // 定义方块的宽高 thumbW: 20, thumbH: 20, boxRect: {}, }; }, methods: { mousemove(event) { // 阻止浏览器默认的行为 event.preventDefault(); // 停止冒泡 event.stopPropagation(); // 方块定位的值 = 鼠标位置 - 方块自身宽高/2 - 父盒子左上角位置的值 // ps1:方块自身宽高/2,作用是使鼠标的位置始终在方块的中心点 // ps2: 父盒子左上角位置的值,是因为event.clientX/Y是采用文档定位,而thumbLeft是绝对定位,所以要矫正偏移的值 this.thumbLeft = event.clientX - this.thumbW / 2 - this.boxRect.left; this.thumbTop = event.clientY - this.thumbH / 2 - this.boxRect.top; }, }, }; </script>
到此已经能够实现鼠标拖动了,但是方块可以拖动到任意位置,下面我们将进行限制。
5.将方块限制在盒子内移动
<template> <div ref="drag" class="Drag"> <!-- 动态计算方块的top与left --> <div class="scroll_thumb" :style="{ width: `${thumbW}px`, height: `${thumbH}px`, top: `${thumbTop}px`, left: `${thumbLeft}px`, }" @mousedown="mousedown" ></div> </div> </template> <script> export default { name: "Drag", data() { return { // 方块的位置 thumbTop: 0, thumbLeft: 0, // 定义方块的宽高 thumbW: 20, thumbH: 20, boxRect: {}, }; }, methods: { mousemove(event) { event.preventDefault(); event.stopPropagation(); this.thumbLeft = event.clientX - this.thumbW / 2 - this.boxRect.left; this.thumbTop = event.clientY - this.thumbH / 2 - this.boxRect.top; // 调用限制 this.setLimit(); }, setLimit() { // 获取方块的右侧与底部的值 const thumbRight = this.thumbLeft + this.thumbW; const thumbBottom = this.thumbTop + this.thumbH; // 当方块的位置超过顶部或左侧,将定位的值设置为0 if (this.thumbLeft <= 0) { this.thumbLeft = 0; } if (this.thumbTop <= 0) { this.thumbTop = 0; } // 当方块的位置超过底部或者右侧,将定位的值设置为父盒子宽高-方块本身宽高的值 if (thumbRight >= this.boxRect.width) { this.thumbLeft = this.boxRect.width - this.thumbW; } if (thumbBottom >= this.boxRect.height) { this.thumbTop = this.boxRect.height - this.thumbH; } }, }, }; </script>
6.完整代码
<template> <div ref="drag" class="Drag"> <!-- 动态计算方块的top与left --> <div class="scroll_thumb" :style="{ width: `${thumbW}px`, height: `${thumbH}px`, top: `${thumbTop}px`, left: `${thumbLeft}px`, }" @mousedown="mousedown" ></div> </div> </template> <script> export default { name: "Drag", data() { return { thumbTop: 0, thumbLeft: 0, thumbW: 20, thumbH: 20, boxRect: {}, }; }, mounted() { this.setBoxRect(); window.addEventListener("resize", this.setBoxRect); }, beforeDestroy() { window.removeEventListener("resize", this.setBoxRect); this.removeMouseEvent(); }, methods: { setBoxRect() { this.boxRect = this.$refs.drag.getBoundingClientRect(); }, mousedown(event) { // 判断是否是鼠标左键 if (event.button !== 0) return; document.addEventListener("mousemove", this.mousemove); document.addEventListener("mouseup", this.mouseup); }, mousemove(event) { event.preventDefault(); event.stopPropagation(); this.thumbLeft = event.clientX - this.thumbW / 2 - this.boxRect.left; this.thumbTop = event.clientY - this.thumbH / 2 - this.boxRect.top; this.setLimit(); }, setLimit() { const thumbRight = this.thumbLeft + this.thumbW; const thumbBottom = this.thumbTop + this.thumbH; if (this.thumbLeft <= 0) { this.thumbLeft = 0; } if (this.thumbTop <= 0) { this.thumbTop = 0; } if (thumbRight >= this.boxRect.width) { this.thumbLeft = this.boxRect.width - this.thumbW; } if (thumbBottom >= this.boxRect.height) { this.thumbTop = this.boxRect.height - this.thumbH; } }, mouseup() { this.removeMouseEvent(); }, removeMouseEvent() { document.removeEventListener("mousemove", this.mousemove); document.removeEventListener("mouseup", this.mouseup); }, }, }; </script> <style scoped> .Drag { position: relative; width: 1000px; height: 600px; border: 1px solid #333; margin: 100px auto; } .Drag .scroll_thumb { position: absolute; background-color: gold; } </style>
7.效果
8.应用
笔者做这个案例是为了实现虚拟列表的滚动条做的技术储备,还有其他应用或想法欢迎评论区留言。
以上就是vue实现盒子内拖动方块移动的示例代码的详细内容,更多关于vue实现盒子内方块移动的资料请关注脚本之家其它相关文章!