vue 移动到图片浮动_基于Vue实现拖拽升级(九宫格拖拽)

  • Post author:
  • Post category:vue


前言

在本文中将会用Vue完成九宫格拖拽效果,同时介绍一下网格布局。具体代码以及demo可以点以下超链接进入

效果实例

Demo

简单了解Grid布局(网格布局)

什么是网格布局CSS网格布局(又称“网格”),是一种二维网格布局系统。CSS在处理网页布局方面一直做的不是很好。一开始我们用的是table(表格)布局,然后用float(浮动),position(定位)和inline-block(行内块)布局,但是这些方法本质上是hack,遗漏了很多功能,例如垂直居中。后来出了flexbox(盒子布局),解决了很多布局问题,但是它仅仅是一维布局,而不是复杂的二维布局,实际上它们(flexbox与grid)能很好的配合使用。Grid布局是第一个专门为解决布局问题而创建的CSS模块.

grid

简单说说网格布局的属性display:grid: 生成块级网格

inline-grid: 生成行内网格

subgrid: 如果网格容器本身是网格项(嵌套网格容器),此属性用来继承其父网格容器的列、行大小。

grid-template-columns设置网格列大小

grid-template-rows设置网格行大小

grid-template-areas设置网格区域

grid-column-gap设置网格列间距

grid-row-gap设置网格行间距

grid-gap缩写形式  grid-gap:

justify-items水平方向对齐方式(在这里只是简单说明)

start: 左对齐

end: 右对齐

center: 居中对齐

stretch: 填满(默认)

align-items垂直方向对齐方式

start: 顶部对齐

end: 底部对齐

center: 居中对齐

stretch:填满(默认)

当然,如果看不懂也不要紧,这里有一篇个人十分喜欢的网格布局的文章。里面介绍得十分详细。可以供大家深入学习网格布局内容。

Vue实现九宫格拖拽

实现九宫格布局/*css*/

.container{    position: relative;   /*实现定位,使得滑块定位相对于此*/

display: grid;        /*定义网格布局*/

width: 300px;    height: 300px;    grid-template-columns: 100px 100px 100px;     /*实现九宫格,行列各三*/

grid-template-rows: 100px 100px 100px;    grid-template-areas: “head1 head2 head3”      /*定义个格子的名称,方便计算*/

“main1 main2 main3”

“footer1 footer2 footer3”;    border: 1px solid #000;    margin: 0 auto;

}  .block{    position: absolute;     /*相对于container定位*/

width: 100px;    height: 100px;    display: flex;        /*flex布局,使得文字在中央*/

justify-content: center;    justify-items: center;    align-items: center;    align-content: center;    user-select: none;      /*用户不可选定文字*/

background: olivedrab;    border: 1px solid #000

}//app.vue

{

{positionX}}

{

{positionY}}

实现拖拽的JS代码部分

在这里我选取一些核心代码出来讲解。代码有所省略,因为代码着实有点长,太占篇幅而且没多大意义,如果需要浏览全部代码可以点击上面的Demo连接。

data () {    return {      positionX:0,      //定义方块的两个坐标

positionY:0,

}

},  methods:{

move(e){      let oDiv = e.target;      //获取点击的目标元素

let gDiv = e.path[1];     //获取点击元素的父级元素

/*获取点击时的偏移位置,在这里要注意一下

**由于我们用的是网格布局,每在一个格子中相对位置都是相对格子来算的,不是相对于父级盒子左上角

**也就是说当你把方块移动到九个格子中任意一个时,方块的位置都是top:0和left:0

*/

//所以这里我们直接取鼠标点击的位置减去点击盒子的偏移位置,也就是0

let disX = e.clientX – 0;

let disY = e.clientY – 0;      document.onmousemove = (e)=>{

//当拖动时,算出的值就刚好是方块的top和left值

let left = e.clientX – disX;        let top = e.clientY – disY;        switch (oDiv.style.gridArea){          case “head1 / head1 / head1 / head1”:this.rangeOfHead1(left,top,oDiv);break;    //实现head1的移动范围

case “head2 / head2 / head2 / head2”:this.rangeOfHead2(left,top,oDiv);break;    //实现head2的移动范围

case “head3 / head3 / head3 / head3”:this.rangeOfHead3(left,top,oDiv);break;    //实现head3的移动范围

case “main1 / main1 / main1 / main1”:this.rangeOfMain1(left,top,oDiv);break;    //实现main1的移动范围

}

};      document.onmouseup = (e)=>{        //当鼠标抬起时,我们要做的事

//通过点击位置和父级元素的偏移判断方块在哪个区域

if(e.clientY-gDiv.offsetTop<100&&e.clientX-gDiv.offsetLeft<100){

//将方块移动到该区域中

this.changeBlock(“head1”,oDiv);

}else if(e.clientY-gDiv.offsetTop>100&&e.clientX-gDiv.offsetLeft<100&&e.clientY-gDiv.offsetTop<200){          this.changeBlock(“main1”,oDiv);

}else if(e.clientY-gDiv.offsetTop>200&&e.clientX-gDiv.offsetLeft<100){          this.changeBlock(“footer1”,oDiv);

}else if(e.clientY-gDiv.offsetTop<100&&e.clientX-gDiv.offsetLeft>100&&e.clientX-gDiv.offsetLeft<200){          this.changeBlock(“head2”,oDiv);

}else if(e.clientY-gDiv.offsetTop<100&&e.clientX-gDiv.offsetLeft>200){          this.changeBlock(“head3”,oDiv);

}else if(e.clientY-gDiv.offsetTop>100&&e.clientX-gDiv.offsetLeft>200&&e.clientY-gDiv.offsetTop<200){          this.changeBlock(“main3”,oDiv);

}else if(e.clientY-gDiv.offsetTop>200&&e.clientX-gDiv.offsetLeft>200){          this.changeBlock(“footer3”,oDiv);

}else if(e.clientY-gDiv.offsetTop>200&&e.clientX-gDiv.offsetLeft>100&&e.clientX-gDiv.offsetLeft<200){          this.changeBlock(“footer2”,oDiv);

}else {          this.changeBlock(“main2”,oDiv);

}        document.οnmοusemοve=null;      //需要把事件监听取消

document.onmousedown = null;    //需要把事件监听取消

//当然,不能忘记我们的动画hhh

oDiv.className = “block animated wobble”;        let removeClass = setTimeout(()=>{

oDiv.className = “block animated”;

},500);

};

},

rangeOfHead1(x,y,oDiv){     //判断head1格子中的可以移动范围

if(x>=200){

x=200;

}else if(x<=0){

x=0;

}      if(y>=200){

y=200;

}else if(y<=0){

y=0;

}

oDiv.style.left = x + ‘px’;

oDiv.style.top = y + ‘px’;      this.positionX = x;      this.positionY = y;

},

rangeOfHead2(x,y,oDiv){     //判断head2格子中的可以移动范围

if(x>=100){

x=100;

}else if(x<=-100){

x=-100;

}      if(y>=200){

y=200;

}else if(y<=0){

y=0;

}

oDiv.style.left = x + ‘px’;

oDiv.style.top = y + ‘px’;      this.positionX = x;      this.positionY = y;

},

changeBlock(blockName,oDiv){    //将方块移入到对应的区域中

this.positionX = 0;      this.positionY = 0;

oDiv.style.gridArea=blockName;

}

},

}

总结

到这里我们把九宫格拖拽实现了,同时学习了Grid(网格布局)。总的做下来,发现用网格布局做网格拖拽更加费事,但是为了后续可以方便一些,也只好捣鼓下来了。到这里我们就把基于Vue的九宫格拖拽实现了,有问题或者发现错误的请指正,谢谢大家

珍惜淡定的心境,苦过后更加清

作者:bb7bb

链接:https://www.jianshu.com/p/ccef46e15f3f



版权声明:本文为weixin_39775896原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。