在日常看法中,我们会遇到不同页面上实现相同的功能,如果一个一个的复制,那么显得太low了,这个时候我们就可以将该功能封装成一个对象 通过new一个对象的方式来进行操作,那么在vue中我们可以通过自定义指令来实现上述操作(PS:可以将一个常用的功能写成一个指令,使用的时候调用以下即可)
第一步,搭建样式,引入vue源码
因为拖动需要使用定位,所以样式中添加定位
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <title>Document</title> </head> <style type="text/css"> #div1 { width: 500px; height: 200px; border: 1px solid #ccc; position: absolute; left: 0; top: 0; } </style> <script src="https://cdn.bootcss.com/vue/2.5.16/vue.min.js"></script> <body> <div id="app"> <div id="div1"></div> </div> </body> </html> |
第二步,启动Vue,注册自定义指令,编写拖拽代码
在页面中使用该自定义指令,需要在该标签写入v-drap
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | <script type="text/javascript"> Vue.directive('drap', { //指令绑定到元素 bind(el, binding) { /* * el 指令绑定的元素,可以用来直接操作dom * binding 一个对象,包含许多的属性 */ el.onmousedown = function (e) { console.log("开始拖动"); let disX = e.clientX - el.offsetLeft; let disY = e.clientY - el.offsetTop; document.onmousemove = function (e) { console.log("拖动中"); el.style.left = e.clientX - disX + "px"; el.style.top = e.clientY - disY + "px"; }; document.onmouseup = function () { document.onmousemove = null; console.log("拖动结束"); }; return false; } } }); new Vue({ el: "#app", }) </script> |
最终源码如下
dom元素中的v-for=” in 10″ 表示该元素循环了10次
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <title>Document</title> </head> <style type="text/css"> #div1 { width: 500px; height: 200px; border: 1px solid #ccc; position: absolute; left: 0; top: 0; } </style> <script src="https://cdn.bootcss.com/vue/2.5.16/vue.min.js"></script> <body> <div id="app"> <div id="div1" v-drap v-for=' in 10'></div> </div> </body> </html> <script type="text/javascript"> Vue.directive('drap', { //指令绑定到元素 bind(el, binding) { /* * el 指令绑定的元素,可以用来直接操作dom * binding 一个对象,包含许多的属性 */ el.onmousedown = function (e) { console.log("开始拖动"); let disX = e.clientX - el.offsetLeft; let disY = e.clientY - el.offsetTop; document.onmousemove = function (e) { console.log("拖动中"); el.style.left = e.clientX - disX + "px"; el.style.top = e.clientY - disY + "px"; }; document.onmouseup = function () { document.onmousemove = null; console.log("拖动结束"); }; return false; } } }); new Vue({ el: "#app", }) </script> |
拓展,我们还可以利用自定义指令的.limit来对拖拽范围进行限制
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <title>Document</title> </head> <style type="text/css"> #div1 { width: 500px; height: 200px; border: 1px solid #ccc; position: absolute; left: 0; top: 0; } </style> <script src="https://cdn.bootcss.com/vue/2.5.16/vue.min.js"></script> <body> <div id="app"> <div id="div1" v-drap.limit v-for=' in 10'></div> </div> </body> </html> <script type="text/javascript"> Vue.directive('drap', { //指令绑定到元素 bind(el, binding) { /* * el 指令绑定的元素,可以用来直接操作dom * 指令传入的参数,修饰符,值,v-指令名称:参数.修饰符=值 * binding 一个对象,包含许多的属性 */ el.onmousedown = function (e) { console.log("开始拖动"); let disX = e.clientX - el.offsetLeft; let disY = e.clientY - el.offsetTop; document.onmousemove = function (e) { let L = e.clientX - disX; let T = e.clientY - disY; if (binding.modifiers.limit) { if(L < 0){ L=0; } }; console.log("拖动中"); el.style.left = L + "px"; el.style.top = T + "px"; }; document.onmouseup = function () { document.onmousemove = null; console.log("拖动结束"); }; return false; } } }); new Vue({ el: "#app", }) </script> |
7