vue指令实现拖动的高级写法

vue

不熟悉vue自定义指令" title="vue自定义指令">vue自定义指令看这里: https://cn.vuejs.org/v2/guide/custom-directive.html

vue指令实现拖动方法很方便也挺简单,但是网上大部分的教程代码,一般都是把代码全部写一个方法里面,代码不够美观,代码逻辑也不太清晰,不推荐这种写法,比如下面这样:

Vue.directives: {

drag: {

// 使用bind会有可能没有渲染完成

inserted: function(el, binding, vnode) {

const _el = el; //获取当前元素

const ref = vnode.context.$refs[binding.value]; // 判断基于移动的是哪一个盒子

const masterNode = ref ? ref : document; // 用于绑定事件

const masterBody = ref ? ref : document.body; // 用于获取高和宽

const mgl = _el.offsetLeft;

const mgt = _el.offsetTop;

const maxWidth = masterBody.clientWidth;

const maxHeight = masterBody.clientHeight;

const elWidth = _el.clientWidth;

const elHeight = _el.clientHeight;

let positionX = 0,

positionY = 0;

_el.onmousedown = e => {

//算出鼠标相对元素的位置,加上的值是margin的值

let disX = e.clientX - _el.offsetLeft + mgl;

let disY = e.clientY - _el.offsetTop + mgt;

masterNode.onmousemove = e => {

//用鼠标的位置减去鼠标相对元素的位置,得到元素的位置

let left = e.clientX - disX;

let top = e.clientY - disY;

// 绑定的值不能滑出基于盒子的范围

left < 0 && (left = 0);

left > (maxWidth - elWidth - mgl) && (left = maxWidth - elWidth - mgl);

top < 0 && (top = 0);

top > (maxHeight - elHeight - mgt) && (top = maxHeight - elHeight - mgt);

//绑定元素位置到positionX和positionY上面

positionX = top;

positionY = left;

//移动当前元素

_el.style.left = left + "px";

_el.style.top = top + "px";

};

// 这里是鼠标超出基于盒子范围之后再松开,会监听不到

document.onmouseup = e => {

masterNode.onmousemove = null;

document.onmouseup = null;

};

};

}

}

}

这里介绍一种比较方美观,逻辑清晰的写法,代码如下:

Vue.directive('drag', {

bind (el, binding) {

el.style.cursor = 'move'

el.style.position = 'fixed'

el.mousedownPoint = {

x: 0,

y: 0

}

// bind 改变函数内部 this 指向,让 this 指向 el

// el.handleMouseup, el.handleMousemove, el.handleMousedown 这三个可以是其他的全局变量

el.handleMouseup = handleMouseup.bind(el)

el.handleMousemove = handleMousemove.bind(el)

el.handleMousedown = handleMousedown.bind(el)

el.addEventListener('mousedown', el.handleMousedown)

document.body.addEventListener('mouseup', el.handleMouseup)

document.body.addEventListener('mousemove', el.handleMousemove)

},

unbind (el) {

document.body.removeEventListener('mouseup', el.handleMouseup)

document.body.removeEventListener('mousemove', el.handleMousemove)

}

});

const handleMousedown = function (e) {

// 这里的this被bind改变了,是el

// 这里的e是 MouseEvent 对象

const initialPosition = this.getBoundingClientRect()

this.style.width = initialPosition.width + 'px'

this.position = {

left: initialPosition.left,

top: initialPosition.top

}

this.readyToMove = true

this.mousedownPoint.x = e.screenX

this.mousedownPoint.y = e.screenY

}

const handleMousemove = function (e) {

if (!this.readyToMove) return false

const position = this.position

position.left = position.left + e.screenX - this.mousedownPoint.x

position.top = position.top + e.screenY - this.mousedownPoint.y

this.mousedownPoint.x = e.screenX

this.mousedownPoint.y = e.screenY

this.style.left = position.left + 'px'

this.style.transform = 'none'

this.style.marginLeft = 0

this.style.marginTop = 0

this.style.top = position.top + 'px'

this.style.bottom = 'auto'

this.style.right = 'auto'

}

const handleMouseup = function (e) {

this.readyToMove = false

}

这种写法主要利用了bind的特性,回一个新的函数,并且这个函数的 this 已经被改成我们想要的 this, 推荐这种写法。

以上是 vue指令实现拖动的高级写法 的全部内容, 来源链接: utcz.com/z/380775.html

回到顶部