Vue实现拖拽升级(九宫格拖拽)
前言
在本文中将会用Vue完成九宫格拖拽效果,同时介绍一下网格布局。
效果实例
简单了解Grid布局(网格布局)
什么是网格布局
CSS网格布局(又称“网格”),是一种二维网格布局系统。CSS在处理网页布局方面一直做的不是很好。一开始我们用的是table(表格)布局,然后用float(浮动),position(定位)和inline-block(行内块)布局,但是这些方法本质上是hack,遗漏了很多功能,例如垂直居中。后来出了flexbox(盒子布局),解决了很多布局问题,但是它仅仅是一维布局,而不是复杂的二维布局,实际上它们(flexbox与grid)能很好的配合使用。Grid布局是第一个专门为解决布局问题而创建的CSS模块.
简单说说网格布局的属性
- display: grid: 生成块级网格 inline-grid: 生成行内网格 subgrid: 如果网格容器本身是网格项(嵌套网格容器),此属性用来继承其父网格容器的列、行大小。
- grid-template-columns 设置网格列大小
- grid-template-rows 设置网格行大小
- grid-template-areas 设置网格区域
- grid-column-gap 设置网格列间距
- grid-row-gap 设置网格行间距
- grid-gap 缩写形式 grid-gap: <grid-row-gap> <grid-column-gap>
- justify-items 水平方向对齐方式(在这里只是简单说明) start: 左对齐 end: 右对齐 center: 居中对齐 stretch: 填满(默认)
- align-items 垂直方向对齐方式 start: 顶部对齐 end: 底部对齐 center: 居中对齐 stretch:填满(默认)
当然,如果看不懂也不要紧,这里有一篇个人十分喜欢的网格布局的文章。里面介绍得十分详细。可以供大家深入学习网格布局内容。
传送门:Grid布局指南
https://www.jianshu.com/p/d183265a8dad
实现九宫格布局
/*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>
实现拖拽的JS代码部分
在这里我选取一些核心代码出来讲解。代码有所省略,因为代码着实有点长,太占篇幅而且没多大意义,如果需要浏览全部代码可以点击上面的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的九宫格拖拽实现了,有问题或者发现错误的请指正,谢谢大家
Vue实现拖拽升级(九宫格拖拽)相关推荐
- vue 移动到图片浮动_基于Vue实现拖拽升级(九宫格拖拽)
前言 在本文中将会用Vue完成九宫格拖拽效果,同时介绍一下网格布局.具体代码以及demo可以点以下超链接进入 效果实例 Demo 简单了解Grid布局(网格布局) 什么是网格布局 CSS网格布局(又称 ...
- vuedraggable能实现自由拖拽功能吗?_基于 vue.js 仿禅道主页拖拽效果
今天给大家分享一个超不错的Vue仿禅道首页拖拽布局VueDndKon. vue-dnd-kon 基于vuedraggable实现的仿禅道首页拖拽项目.支持模块上下及左右自由拖动布局. 主页分为左右两栏 ...
- 微信小程序图片上传九宫格拖拽组件
微信小程序图片上传&九宫格拖拽组件 前言 图片上传加九宫格拖拽是一个比较常用的组件,常用于发帖或者评论等内容上传模块,我这篇九宫格拖拽的思路是借鉴了一款优雅的小程序拖拽排序组件实现这篇文章 实 ...
- Element UI表格拖拽(vue中) —— 行拖拽、列拖拽
目录 安装依赖 vuedraggable 实现拖拽的要点 行拖拽要点 列拖拽要点 完整范例代码 安装依赖 vuedraggable 安装 vuedraggable 的同时,会自动安装 sortabl ...
- Vue 实现拖拽模块(一)拖拽添加组件
本文主要介绍了vue拖拽组件实现构建页面的简单实现,文中通过示例代码介绍,感兴趣的小伙伴们可以了解一下 本文主要介绍了 Vue拖拽添加组件的简单实现,具体如下: 效果图 实现思路 使用 H5 的新特性 ...
- java和vue实现拖拽可视化_Vue拖拽组件开发实例详解
摘要:这篇Vue栏目下的"Vue拖拽组件开发实例详解",介绍的技术点是"Vue拖拽组件开发实例.vue拖拽组件.拖拽组件.组件开发.开发实例.实例详解",希望对 ...
- vue 悬浮图标_vue实现可拖拽移动悬浮球
拖拽移动悬浮球 需求拆解 1.元素悬浮于全屏 2.元素可拖拽 3.元素拖拽结束后会吸附贴壁 4.元素单击唤出菜单 5.菜单展开时点击空白处关闭菜单 6.菜单不可拖拽 7.元素拖拽时菜单不打开 8.元素 ...
- vue + element 中tab标签页拖拽(拖动) sortablejs插件实现
tab签拖拽更换位置 业务需求 效果图 1.npm安装sortable.js 2.html代码块 3. 在script下导入 4.js逻辑片段(**const el 必须找到自己拖拽的那一列** ) ...
- js控制文件拖拽,获取拖拽内容。
在用户拖拽文件到浏览器的某个元素上时,js可以监听到与拖拽相关的事件,并对拖拽结果进行处理,本文讨论下和拖拽文件相关的一些问题,不过没有处理太多关于兼容性的问题. 拖拽事件 js能够监听到拖拽的事件有 ...
最新文章
- redis的redisvCommand的%b
- lua虚拟机字节码修改_Java虚拟机(JVM)面试题大集合
- java freemarker 分页_10小时入门java开发04 springboot+freemarker+bootstrap快速实现分页功能...
- numpy 二维、高维矩阵重新排列轴与数据(轴转换)
- 08.CXF发布WebService(Java项目)
- OpenStack Rocky Octavia 的实现与分析(零)架构简介
- CreatePipe()函数
- jpg格式如何转eps路径_jpg/png格式图片转eps格式的方法总结
- FPGA verilog 临近插值任意比例视频缩放代码
- 推荐13个高清优质无版权图库
- 2022A特种设备相关管理(电梯)特种作业证考试题库及在线模拟考试
- 唯品会顺丰快递面单模板_快递模板
- 电脑白屏,电脑白屏怎么办
- 微信小程序Nginx环境配置
- chmod 777 修改文件权限
- logback日志pattern_Logback日志基础及自定义配置代码实例
- VIPS算法对搜索引擎的意义[转载]
- linux内核空间和用户空间的是怎样区别的,如何交互,如何从用户空间进入内核空间
- 国内第一款“专业”的个人知识管理软件工具正式推出
- 十六进制字符串转整型