在本文中将会用Vue完成九宫格拖拽效果,同时介绍一下网格布局。具体代码以及demo能够点如下超连接进入css
传送门:Demo以及完整代码链接vue
CSS网格布局(又称“网格”),是一种二维网格布局系统。CSS在处理网页布局方面一直作的不是很好。一开始咱们用的是table(表格)布局,而后用float(浮动),position(定位)和inline-block(行内块)布局,可是这些方法本质上是hack,遗漏了不少功能,例如垂直居中。后来出了flexbox(盒子布局),解决了不少布局问题,可是它仅仅是一维布局,而不是复杂的二维布局,实际上它们(flexbox与grid)能很好的配合使用。Grid布局是第一个专门为解决布局问题而建立的CSS模块.
display:app
grid-template-columns布局
grid-template-rows学习
grid-template-areasflex
grid-column-gap动画
grid-row-gapthis
grid-gapflexbox
justify-itemsspa
align-items
固然,若是看不懂也没关系,这里有一篇我的十分喜欢的网格布局的文章。里面介绍得十分详细。能够供你们深刻学习网格布局内容。
传送门:Grid布局指南
Demo地址: Demo以及完整代码
/*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 <div id="app"> <div class="container"> <transition > <div class="block animated" :style="{top:this.positionY,left:this.positionX,gridArea:'main2'}" @mousedown="move" ref="block"> {{positionX}} {{positionY}} </div> </transition> </div> </div>
在这里我选取一些核心代码出来说解。代码有所省略,由于代码着实有点长,太占篇幅并且没多大意义,若是须要浏览所有代码能够点击上面的Demo链接。
<script> //引入animate.css 没有手撕css动画,直接用了animate.css实现咱们的动画效果 import animate from 'animate.css'; export default { name: 'app', 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.onmousemove=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; } }, } </script>
到这里咱们把九宫格拖拽实现了,同时学习了Grid(网格布局)。总的作下来,发现用网格布局作网格拖拽更加费事,可是为了后续能够方便一些,也只好捣鼓下来了。到这里咱们就把基于Vue的九宫格拖拽实现了,有问题或者发现错误的请指正,谢谢你们
珍惜淡定的心境,苦事后更加清