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.offsetLeftel.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) { }
}
posted @ 2022-11-09 15:53  槑孒  阅读(204)  评论(0编辑  收藏  举报