开发一个可自定义组件化门户配置页面,期间采用了vue框架做为前端视图引擎,做为一个刚入手vue的萌新,开发第一个功能就遇到了拦路虎。须要一个拖动而且可改变大小的容器盒子。当时查看vue开发文档,查找github都没找到一个本身欢心的实现,因此与其求人,还不如求己。因此vuedragx这个轮子就有了,x
表明它不止可拖动。
github地址:github.com/464884492/v…javascript
因此有了以上思路,就须要一次掌握三个重要知识php
记住,无论使用什么样的框架,须要学习某种技能,须要学习api各类方法的用法,最好的途径就是查看对应官方文档html
vue 开发自定义指令地址 cn.vuejs.org/v2/guide/cu…
通读一篇,而后敲黑板画重点前端
官方是么说的 在 Vue2.0 中,代码复用和抽象的主要形式是组件。然而,有的状况下,你仍然须要对普通 DOM 元素进行底层操做,这时候就会用到自定义指令vue
显而易见,经过须要使用鼠标产生的位移,经过啥啥实在是比较为难在下了java
针对vue指令,官方给开发这提供了几个勾子函数,来注入开发者开发的功能,所谓的钩子函数,我的理解也就是在正常的代码中插入预埋的未实现的函数接口node
vue对开发着提供(bind、inserted、update、componentUpdated、unbind)注入点。ios
每个钩子都带有参数 el、binding、vnode、oldVnodec++
{dragable:true,resizeable:true}
,不过vuedragx并无使用此方法传值,统一经过binding.value传值关于vue指令的钩子函数,参数等相关说明,基本从官网引用过来的。我以为有必要再次在强调如下,使用第三方的框架,最好途径就是查阅官方文档。其次能够看看对应的源码,若是有的话。git
上边在vue指令介绍中,强调了查阅官方文档的重要性,那么针对javascript的api又该在那里查阅呢?固然是 MDN,没有第二
MDN中关于MouseEvent说明的地址: developer.mozilla.org/zh-CN/docs/…,开发vuedragx须要MouseEvent中最重要的两个属性MouseEvent.pageX
、MouseEvent.pageY
这个属性将基于文档的边缘,考虑任何页面的水平方向上的滚动。举个例子,若是页面向右滚动 200px 并出现了滚动条,这部分在窗口以外,而后鼠标点击距离窗口左边 100px 的位置,pageX 所返回的值将是 300。
作为延伸,分别查看了MonuseEvent中其余对应坐标的属性
因此,他们之间的关系应该是这样的
用过jQuery的小伙伴,应该多少了解 trigger``triggerHandler
方法,触发自定义事件,有了jq的帮助,自定义事件用的是那么驾轻就熟,如丝版顺滑。作为对比,咱们先看看jq是如何使用自定义事件的
// 添加一个适当的事件监听器
$(
'#foo').on(
'custom',
function(event, param1, param2) {
alert(param1 +
"\n" + param2);
});
$(
'#foo').trigger(
'custom', [
'Custom',
'Event']);
复制代码
对,就是这么简单,定义,传参一鼓作气!
不过用Vue后,这些功能都要用原生的代码实现,业界也愈来愈强调原生代码呼声也愈来愈高。或许这句是es标准逐步完善,浏览器逐步兼容新api带来的利好。这里应该向IE6致敬(逃)。
言归正传,标准接口是如何使用自定义事件的呢?因而有找到了MDN developer.mozilla.org/zh-CN/docs/…,找到了demo
// 添加一个适当的事件监听器
obj.addEventListener(
"custom",
function(e) {
console.log(
JSON.stringify(e.detail));
})
// 建立并分发事件
var event =
new CustomEvent(
"custom", {
"detail":{
"Custom":
true}});
obj.dispatchEvent(event)
复制代码
在我看来,定义事件的样子,基本没变,惟一参数传递变得复杂了。总有那么一丢丢不美好。
鼠标在目标对象上下左边边缘移动时,鼠标须要显示不一样的resize样式,提醒用户当前可操做的类型。基本思路是获取当前对象的在文档对应的left和top值,与上边讲解的MouseEvent中的 pageX、pageY加上可容忍的边沿值作比较,分别分如下几种状况
因此具体代码是这样的
判断当前鼠标是否在拖动对象上就没有那么费劲了,直接在onmousemove事件中经过
e.target.classList.contains(cfg.dragBarClass)
判断便可
经过计算获得鼠标移动的deltx和delty值,分别更新width和heigth属性。当前在向左和向上调整大小,还须要调整对一个的left和height属性值
拖动,不改变目标对象大小,直接用计算的deltx和delty更新对应的left和top属性便可,若是须要限制移动区域,须要计算父容器对应内边距的坐标
function setConstraint(data) {
if (cfg.dragContainerId) {
let constraintDom =
document.querySelector(
"#" + cfg.dragContainerId);
let constraintRect = constraintDom.getBoundingClientRect();
if (data.left <=
0) data.left =
0;
if (data.top <=
0) data.top =
0;
if (data.top + data.height+data.borderTop+data.borderBottom >= constraintRect.height) data.top = constraintRect.height - data.height-data.borderTop-data.borderBottom;
if (data.left + data.width+data.borderLeft+data.borderRight > constraintRect.width) data.left = constraintRect.width - data.width-data.borderLeft-data.borderRight;
}
}
复制代码
虽然功能不大,但要把每个环节说清楚,感受仍是很费力。真羡慕那些会写书的开发人员,文档能力那是至关的好。写文档真的比不了写代码,不过仍是要写,否则别人怎么知道你代码是作啥的。