最近公司有个需求,需要实现组件拖拽,实现方式:主要通过vue组件实现,通过在网上查找资料,发现没有真正符合需求的例子,但是有一些功能可以参考,无奈之下打算自己封装一个,一方面也想证明一下自己的能力,此篇博文只是记录一下,方便以后遇到此类问题,有个参考。
经过一段时间的研究需求发现需要实现组件的自由拖拽,以及放大缩小等功能,需要脚踏实地的一点一点的封装,下面列举一下主要实现的功能点:
1.封装点组件 ,主要实现在容器内自由拖拽;
2.封装正方形组件,和点组件结合使用,通过点组件创建8个坐标点作为可拖拽的对象,根据点坐标的位移实现正方形的放大缩小;
3.使用canvas实现创建各种图形界面;
下面开始点组件的封装:
创建html
<template>
<div class="square" v-customSquare ref="square" style="position:absolute;left:20px;top:50px;">
<porint v-customPoint="1" :pointType="1" @movePoint="movePoint1"></porint>
<porint v-customPoint="2" :pointType="1" @movePoint="movePoint2"></porint>
<porint v-customPoint="3" :pointType="1" @movePoint="movePoint3"></porint>
<porint v-customPoint="4" :pointType="1" @movePoint="movePoint4"></porint>
<porint v-customPoint="5" :pointType="1" @movePoint="movePoint5"></porint>
<porint v-customPoint="6" :pointType="1" @movePoint="movePoint6"></porint>
<porint v-customPoint="7" :pointType="1" @movePoint="movePoint7"></porint>
<porint v-customPoint="8" :pointType="1" @movePoint="movePoint8"></porint>
</div>
</template>
编写脚本
<script>
import porint from '@/components/newCommon/util/point.vue'; //引用点组件
export default {
name:'square',
components:{
porint, //使用点组件
},
data(){
return{
width:300, //定义正方形 组件宽
height:300, //定义正方形组件高
obj:{}, //定义空对象
}
},
directives:{ 引入指令
customSquare:{ 创建正方形指令
inserted(el,binding,vnode){ //绑定组件
let obj = binding.value; //获取绑定组件的值
el.style.width=vnode.context.width+'px'; //获取组件内定义的宽
el.style.height=vnode.context.height+'px';//获取组件内定义的高
},
update: function (newValue, oldValue) { //组件更新时获取组件更新后的内容
// 根据获得的新值执行对应的更新
// 对于初始值也会被调用一次
},
},
customPoint:{ //创建点组件的指令
inserted(el,binding,vnode){ //绑定组件
let index =binding.value; //获取绑定组件的值
//定义坐标点 index 1. 左上 、2.中上、 3.右上、 4.中左、5.中右、6.左下、7.中下、8.右下、共计8个坐标点,采用绝对定位的方式。
if(index == 1) {
el.style.left='0%';
el.style.top='0%';
}else if(index == 2) {
el.style.left='50%'
el.style.top='0%';
}else if(index == 3){
el.style.left='100%';
el.style.top='0%'
}
else if(index == 4){
el.style.left='0%'
el.style.top='50%'
}
else if(index == 5){
el.style.left='100%'
el.style.top='50%'
}
else if(index == 6){
el.style.left='0%'
el.style.top='100%'
}
else if(index == 7){
el.style.left='50%'
el.style.top='100%'
}
else if(index == 8){
el.style.left='100%'
el.style.top='100%'
}
//console.log(el.parentNode,'el.parentNode.style.width');
},
update: function (newValue, oldValue) {
// 根据获得的新值执行对应的更新
// 对于初始值也会被调用一次
//console.log(newValue,oldValue,'update');;
},
}
},
methods:{
//坐标点1 的运动范围。
movePoint1:(parentObj,odiv,x,y,e,parentPositionWidth,parentPositionLeft,parentPositionTop,parentPositionHeight) =>{
// 获取拖拽元素的位置
let left = e.clientX - x; //获取鼠标在x轴移动的偏移量
let top = e.clientY - y;//获取鼠标在y轴移动的偏移量
//console.log(x+parentObj.style.width.split('p')[0] * 1);
// 允许鼠标向左移动的最大范围
if(left<= -parentPositionLeft){
left =-parentPositionLeft;
}
// 允许鼠标向右移动的最大范围
if (left >= parentPositionWidth){
//document.documentElement.clientWidth 屏幕的可视宽度
left =parentPositionWidth;
}
// 允许鼠标向上移动的最大范围
if (top <= -parentPositionTop) {
top = -parentPositionTop;
}
// 允许鼠标向下移动的最大范围
if (top >= parentPositionHeight){
// document.documentElement.clientHeight 屏幕的可视高度
top = parentPositionHeight;
}
//通过点坐标的移动设置 父div 的宽度 如向右移动,则用父div宽度 - 鼠标移动的偏移量
parentObj.style.width = (parentPositionWidth -left)+'px';
//同理通过点坐标的移动设置,父div 向左偏移的位置 如向右移动,则用父div向左偏移的位置 + 鼠标移动的偏移量
parentObj.style.left = parentPositionLeft + left + 'px';
//同理通过点坐标的移动设置,父div的高度,如向下移动,则用父div的高度 - 向下移动的偏移量
parentObj.style.height =(parentPositionHeight -top)+'px';
//同理通过点坐标的移动设置,父div的 向下的偏移位置,如向下移动,则用父div向下偏移的位置 + 向下移动的偏移量
parentObj.style.top = (parentPositionTop+top)+'px';
},
//以上就是第一个点移动范围和div可以实现自动方法缩小功能,一下7个点就不添加注释,大家可以把代码粘贴到本地体会一下。
movePoint2:(parentObj,odiv,x,y,e,parentPositionWidth,parentPositionLeft,parentPositionTop,parentPositionHeight) =>{
let top = e.clientY - y;
if (top <= -parentPositionTop) {
top = -parentPositionTop;
} else if (top >= parentPositionHeight){
// document.documentElement.clientHeight 屏幕的可视高度
top = parentPositionHeight
}
parentObj.style.height =(parentPositionHeight -top)+'px';
parentObj.style.top = (parentPositionTop+top)+'px';
},
movePoint3:(parentObj,odiv,x,y,e,parentPositionWidth,parentPositionLeft,parentPositionTop,parentPositionHeight) =>{
let left = e.clientX - x;
let top = e.clientY - y;
//console.log(x+parentObj.style.width.split('p')[0] * 1);
// 把拖拽元素 放到 当前的位置
if(left<=0){
left =0;
}
if (left >= 1000 - odiv.offsetWidth - parentPositionLeft){
//document.documentElement.clientWidth 屏幕的可视宽度
left =1000 - odiv.offsetWidth- parentPositionLeft;
}
if (top <= -parentPositionTop) {
top = -parentPositionTop;
} else if (top >= parentPositionHeight){
// document.documentElement.clientHeight 屏幕的可视高度
top = parentPositionHeight;
}
parentObj.style.width = left+'px';
parentObj.style.height =(parentPositionHeight -top)+'px';
parentObj.style.top = (parentPositionTop+top)+'px';
// parentObj.style.left = parentPositionLeft + left + 'px';
},
movePoint4:(parentObj,odiv,x,y,e,parentPositionWidth,parentPositionLeft,parentPositionTop,parentPositionHeight) =>{
let left = e.clientX - x;
//console.log(x+parentObj.style.width.split('p')[0] * 1);
// 把拖拽元素 放到 当前的位置
if(left<= -parentPositionLeft){
left =-parentPositionLeft;
}
if (left >= parentPositionWidth){
//document.documentElement.clientWidth 屏幕的可视宽度
left =parentPositionWidth;
}
parentObj.style.width = (parentPositionWidth -left)+'px';
parentObj.style.left = parentPositionLeft + left + 'px';
},
movePoint5:(parentObj,odiv,x,y,e,parentPositionWidth,parentPositionLeft,parentPositionTop,parentPositionHeight) =>{
let left = e.clientX - x;
//console.log(x+parentObj.style.width.split('p')[0] * 1);
// 把拖拽元素 放到 当前的位置
if(left<=0){
left =0;
}
if (left >= 1000 - odiv.offsetWidth - parentPositionLeft){
//document.documentElement.clientWidth 屏幕的可视宽度
left =1000 - odiv.offsetWidth- parentPositionLeft;
}
// odiv.style.left = left + "px";
// odiv.style.top = top + "px";
parentObj.style.width = left+'px';
parentObj.style.height =(parentPositionHeight -top)+'px';
parentObj.style.top = (parentPositionTop+top)+'px';
},
movePoint6:(parentObj,odiv,x,y,e,parentPositionWidth,parentPositionLeft,parentPositionTop,parentPositionHeight) =>{
let left = e.clientX - x;
let top = e.clientY - y;
//console.log(x+parentObj.style.width.split('p')[0] * 1);
// 把拖拽元素 放到 当前的位置
if(left<= -parentPositionLeft){
left =-parentPositionLeft;
}
if (left >= parentPositionWidth){
//document.documentElement.clientWidth 屏幕的可视宽度
left =parentPositionWidth;
}
if (top <=0) {
top = 0;
} else if (top >= 600 -odiv.offsetHeight - parentPositionTop){
// document.documentElement.clientHeight 屏幕的可视高度
top = 600 -odiv.offsetHeight - parentPositionTop;
}
// odiv.style.left = left + "px";
// odiv.style.top = top + "px";
parentObj.style.width = (parentPositionWidth -left)+'px';
parentObj.style.left = parentPositionLeft + left + 'px';
parentObj.style.height =top+'px';
},
movePoint7:(parentObj,odiv,x,y,e,parentPositionWidth,parentPositionLeft,parentPositionTop,parentPositionHeight) =>{
let top = e.clientY - y;
//console.log(x+parentObj.style.width.split('p')[0] * 1);
// 把拖拽元素 放到 当前的位置
if (top <=0) {
top = 0;
} else if (top >= 600 -odiv.offsetHeight - parentPositionTop){
// document.documentElement.clientHeight 屏幕的可视高度
top = 600 -odiv.offsetHeight - parentPositionTop;
}
parentObj.style.height =top+'px';
},
movePoint8:(parentObj,odiv,x,y,e,parentPositionWidth,parentPositionLeft,parentPositionTop,parentPositionHeight) =>{
let left = e.clientX - x;
let top = e.clientY - y;
//console.log(x+parentObj.style.width.split('p')[0] * 1);
// 把拖拽元素 放到 当前的位置
if(left<=0){
left =0;
}
if (left >= 1000 - odiv.offsetWidth - parentPositionLeft){
//document.documentElement.clientWidth 屏幕的可视宽度
left =1000 - odiv.offsetWidth- parentPositionLeft;
}
if (top <=0) {
top = 0;
} else if (top >= 600 -odiv.offsetHeight - parentPositionTop){
// document.documentElement.clientHeight 屏幕的可视高度
top = 600 -odiv.offsetHeight - parentPositionTop;
}
parentObj.style.width = left+'px';
parentObj.style.height =top+'px';
},
}
}
</script>