vue自定义指令 v-move | 元素可移动
在元素中添加v-move
指令,使用该元素的第一个子元素作为点击目标,进行父元素拖动.
(一般都是选中元素的一部分,带动整个元素的移动的吧~)
<template>
<div v-move class="file-tool">
<span class="desc">文件</span>
<img src="~/assets/images/dataProcessing/addData.png" alt="" title="添加数据" @click="addData">
<img src="~/assets/images/dataProcessing/exportMap.png" alt="" title="导出地图" @click="exportMap">
......
</div>
</template>
注意:不要用类似于transform: translate(-50%, -50%);
的定位,否则会造成el.offsetLeft
,el.offsetTop
定位出问题!
更多详情请问度娘,什么样式属性会影响元素offsetLeft、offsetTop的值.
// 单组件下自定义指令
const vMove = (el) => {
let moveElement = el.firstElementChild;
const mouseDown = (e) => {
// X,Y为计算的偏移量,就是鼠标点击的位置相对于元素左上角圆点的距离
let X = e.clientX - el.offsetLeft;
let Y = e.clientY - el.offsetTop;
const move = (e) => {
// 0 < left && left < window.innerWidth - el.offsetWidth 保证移动过程中,元素不超出窗口
let left = e.clientX - X;
if (0 < left && left < window.innerWidth - el.offsetWidth) {
el.style.left = left + 'px';
}
// 0 < top && top < window.innerHeight - el.offsetHeight 保证移动过程中,元素不超出窗口
let top = e.clientY - Y;
if (0 < top && top < window.innerHeight - el.offsetHeight) {
el.style.top = top + 'px';
}
}
document.addEventListener('mousemove', move)
document.addEventListener('mouseup', () => {
document.removeEventListener('mousemove', move)
})
}
moveElement.addEventListener('mousedown', mouseDown);
}
点击查看代码
// 自定义指令
const vMove = {
mounted(el) {
let moveElement = el.firstElementChild;
el.mouseDown = (e) => {
// X,Y为计算的偏移量,就是鼠标点击的位置相对于元素左上角圆点的距离
let X = e.clientX - el.offsetLeft;
let Y = e.clientY - el.offsetTop;
const move = (e) => {
// 0 < left && left < window.innerWidth - el.offsetWidth 保证移动过程中,元素不超出窗口
let left = e.clientX - X;
if (0 < left && left < window.innerWidth - el.offsetWidth) {
el.style.left = left + 'px';
}
// 0 < top && top < window.innerHeight - el.offsetHeight 保证移动过程中,元素不超出窗口
let top = e.clientY - Y;
if (0 < top && top < window.innerHeight - el.offsetHeight) {
el.style.top = top + 'px';
}
}
document.addEventListener('mousemove', move)
document.addEventListener('mouseup', () => {
document.removeEventListener('mousemove', move)
})
}
moveElement.addEventListener('mousedown', el.mouseDown);
},
// 解绑事件
beforeUnmount(el) {
el.firstElementChild.removeEventListener('mousedown', el.mouseDown)
}
}
全局自定义指令
app.directive('move', {
mounted(el) {
let moveElement = el.firstElementChild;
el.mouseDown = (e) => {
// X,Y为计算的偏移量,就是鼠标点击的位置相对于元素左上角圆点的距离
let X = e.clientX - el.offsetLeft;
let Y = e.clientY - el.offsetTop;
const move = (e) => {
// 0 < left && left < window.innerWidth - el.offsetWidth 保证移动过程中,元素不超出窗口
let left = e.clientX - X;
if (0 < left && left < window.innerWidth - el.offsetWidth) {
el.style.left = left + 'px';
}
console.log(left, window.innerWidth, el.offsetWidth)
// 0 < top && top < window.innerHeight - el.offsetHeight 保证移动过程中,元素不超出窗口
let top = e.clientY - Y;
if (0 < top && top < window.innerHeight - el.offsetHeight) {
el.style.top = top + 'px';
}
console.log(top, window.innerHeight, el.offsetHeight)
}
document.addEventListener('mousemove', move)
document.addEventListener('mouseup', () => {
document.removeEventListener('mousemove', move)
})
}
moveElement.addEventListener('mousedown', el.mouseDown);
},
// 解绑事件
beforeUnmount(el) {
el.firstElementChild.removeEventListener('mousedown', el.mouseDown)
}
})
自定义指令的生命周期
const vMoveTest = {
// 在绑定元素的 attribute 前
// 或事件监听器应用前调用
created(el, binding, vnode, prevVnode) {},
// 在元素被插入到 DOM 前调用
beforeMount(el, binding, vnode, prevVnode) { },
// 在绑定元素的父组件
// 及他自己的所有子节点都挂载完成后调用
mounted(el, binding, vnode, prevVnode) { },
// 绑定元素的父组件更新前调用
beforeUpdate(el, binding, vnode, prevVnode) { },
// 在绑定元素的父组件
// 及他自己的所有子节点都更新后调用
updated(el, binding, vnode, prevVnode) { },
// 绑定元素的父组件卸载前调用
beforeUnmount(el, binding, vnode, prevVnode) { },
// 绑定元素的父组件卸载后调用
unmounted(el, binding, vnode, prevVnode) { }
}