本文实例讲述了Vue使用自定义指令实现拖拽行为。分享给大家供大家参考,具体如下:需求通过自定义指令的方式实现拖拽效果,预期的使用方式为:


XXXX





XXXX


更重要的一个需求点:

拖拽元素内部的子元素可以自行阻止拖拽行为
拖拽元素内部的子元素可以自行阻止拖拽行为比如:


test





test


曾经使用过vue-resizable,由于该组件是通过事件捕获的方式实现的,拖拽元素的子元素也会触发拖拽行为,不符合开发需求,所以自行实现了拖拽指令,相关源码如下。vue-resizable无任何依赖,复制即可使用源码
/**
* @file 自定义拖拽命令
*/
import Vue from 'vue';
const Drag = {

install(Vue: any) {

// 如需禁止拖拽元素内部某些元素触发拖拽,在内部不可触发拖拽元素上添加@mousedown.native.stop即可

Vue.directive('drag', {

bind(el: any) {

el.style.position = 'absolute';

el.style.zIndex = el.style.zIndex || '3000';

},


inserted(el: any) {

// 设置元素初始位置

const boundingClientRect = el.getBoundingClientRect();

el.style.left = boundingClientRect.x + 'px';

el.style.top = boundingClientRect.y + 'px';

// 将拖拽元素置于body子元素,防止被relative的父元素遮挡

document.body.appendChild(el);


let originX: number;

let originY: number;

const mouseDownHandler = (evt: MouseEvent) => {

originX = evt.clientX - el.offsetLeft;

originY = evt.clientY - el.offsetTop;

el.style.cursor = 'pointer';

};

const mouseMoveHandler = (evt: MouseEvent) => {

if (evt.buttons === 1 && originX && originY) {

el.style.left = evt.clientX - originX + 'px';

el.style.top = evt.clientY - originY + 'px';

}

};

const mouseUpHandler = () => {

el.style.cursor = 'default';

};

el.addEventListener('mousedown', mouseDownHandler);

el.addEventListener('mousemove', mouseMoveHandler);

el.addEventListener('mouseup', mouseUpHandler);

el.__mouseDownHandler__ = mouseDownHandler;

el.__mouseMoveHandler__ = mouseMoveHandler;

el.__mouseUpHandler__ = mouseUpHandler;

},


unbind(el: any) {

el.removeEventListener('mousedown', el.__mouseDownHandler__);

el.removeEventListener('mousemove', el.__mouseMoveHandler__);

el.removeEventListener('mouseup', el.__mouseUpHandler__);

// 当父组件销毁触发unbind的时候需要手动删除这个节点,不然会一直存留在body中

el.parentNode.removeChild(el);

}

});

}
};
Vue.use(Drag);
export default Drag;


/**
* @file 自定义拖拽命令
*/
import Vue from 'vue';
const Drag = {

install(Vue: any) {

// 如需禁止拖拽元素内部某些元素触发拖拽,在内部不可触发拖拽元素上添加@mousedown.native.stop即可

Vue.directive('drag', {

bind(el: any) {

el.style.position = 'absolute';

el.style.zIndex = el.style.zIndex || '3000';

},


inserted(el: any) {

// 设置元素初始位置

const boundingClientRect = el.getBoundingClientRect();

el.style.left = boundingClientRect.x + 'px';

el.style.top = boundingClientRect.y + 'px';

// 将拖拽元素置于body子元素,防止被relative的父元素遮挡

document.body.appendChild(el);


let originX: number;

let originY: number;

const mouseDownHandler = (evt: MouseEvent) => {

originX = evt.clientX - el.offsetLeft;

originY = evt.clientY - el.offsetTop;

el.style.cursor = 'pointer';

};

const mouseMoveHandler = (evt: MouseEvent) => {

if (evt.buttons === 1 && originX && originY) {

el.style.left = evt.clientX - originX + 'px';

el.style.top = evt.clientY - originY + 'px';

}

};

const mouseUpHandler = () => {

el.style.cursor = 'default';

};

el.addEventListener('mousedown', mouseDownHandler);

el.addEventListener('mousemove', mouseMoveHandler);

el.addEventListener('mouseup', mouseUpHandler);

el.__mouseDownHandler__ = mouseDownHandler;

el.__mouseMoveHandler__ = mouseMoveHandler;

el.__mouseUpHandler__ = mouseUpHandler;

},


unbind(el: any) {

el.removeEventListener('mousedown', el.__mouseDownHandler__);

el.removeEventListener('mousemove', el.__mouseMoveHandler__);

el.removeEventListener('mouseup', el.__mouseUpHandler__);

// 当父组件销毁触发unbind的时候需要手动删除这个节点,不然会一直存留在body中

el.parentNode.removeChild(el);

}

});

}
};
Vue.use(Drag);
export default Drag;

希望本文所述对大家vue.js程序设计有所帮助。