Vue.js----创建自定义指令实现拖拽效果

创建自定义指令的2种方式:全局、局部
1、全局
Vue.directive(name,(el,{value,modifiers})=>{})
说明:name指令名称;()=>{}指令实现的函数;el当前元素;对象{value表达式的结果,modifiers修饰符}
2、局部
let vm = new Vue({
  directives:{name:(el,{value,modifiers})=>{}}
})
以下通过全局和局部分别创建自定义指令来实现拖拽效果,请见下面代码(局部方式暂时已被注释):
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>vue-drag</title>
    <style>
        *{
            margin:0;
            padding:0;
        }
        body{
            position: relative;
        }
        #box1,#box2,#box3,#box4,#box5{
            width:100px;
            height:100px;
            background: red;
            position: absolute;
            left:0;
            top:0;
            color:#fff;
        }
        #box2{
            left:120px;
            background: blue;
        }
        #box3{
            left:240px;
            background: yellow;
        }
        #box4{
            left:360px;
            background: green;
        }
        #box5{
            left:480px;
            background: purple;
        }
    </style>
</head>
<body>
    <div id="app">
        <div id="box1" v-drag.x.y="flag">1-XY轴拖拽</div>
        <div id="box2" v-drag="flag">2-XY轴拖拽</div>
        <div id="box3" v-drag.x="flag">3-仅X轴拖拽</div>
        <div id="box4" v-drag.y="flag">4-仅Y轴拖拽</div>
        <div id="box5" v-drag="flag2">5-禁止拖拽</div>
    </div>
</body>
</html>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    //全局自定义指令
    Vue.directive("drag",(el,{value,modifiers})=>{
        if(value){
            let {x,y} = modifiers;
            //目标对象的鼠标按下事件
            el.onmousedown = (e) => {
                //鼠标相对元素的位置
                let disX = e.clientX - el.offsetLeft;
                let disY = e.clientY - el.offsetTop;
                //document的鼠标移动事件
                document.onmousemove = (e)=>{
                    //元素的位置=鼠标位置-鼠标相对元素的位置
                    let leftA = e.clientX - disX;    
                    let topA = e.clientY - disY;
                    //设置边界
                    let left = leftA < 0 ? 0 : leftA > window.innerWidth - el.offsetWidth ? window.innerWidth - el.offsetWidth : leftA;
                    console.log(document.body.clientHeight)
                    let top = topA < 0 ? 0 : topA > window.innerHeight - el.offsetHeight ? window.innerHeight - el.offsetHeight : topA;
                    //判断x轴还是y轴移动:当xy均存在或均不存在时默认xy轴均能拖拽,仅x则x轴拖拽,仅y则y轴拖拽
                    if((x&&y)||(!x && !y)){
                        el.style.left = left + 'px';
                        el.style.top = top + 'px';
                    }else if(x){
                        el.style.left = left + 'px';
                    }else if(y){
                        el.style.top = top + 'px';
                    }
                }
                //document的鼠标弹起事件:清空鼠标移动和弹起事件
                document.onmouseup = (e)=>{
                    document.onmousemove = null;
                    document.onmouseup = null;
                }
            }
        }
    })
    
    let vm = new Vue({
        el:'#app',
        data:{
            flag:true,
            flag2:false,
        },
        //局部自定义指令
        /*
        directives: {
            "drag":(el,{value,modifiers})=>{
                if(value){
                    let {x,y} = modifiers;
                    //目标对象的鼠标按下事件
                    el.onmousedown = (e) => {
                        //鼠标相对元素的位置
                        let disX = e.clientX - el.offsetLeft;
                        let disY = e.clientY - el.offsetTop;
                        //document的鼠标移动事件
                        document.onmousemove = (e)=>{
                            //元素的位置=鼠标位置-鼠标相对元素的位置
                            let leftA = e.clientX - disX;    
                            let topA = e.clientY - disY;
                            //设置边界
                            let left = leftA < 0 ? 0 : leftA > window.innerWidth - el.offsetWidth ? window.innerWidth - el.offsetWidth : leftA;
                            console.log(document.body.clientHeight)
                            let top = topA < 0 ? 0 : topA > window.innerHeight - el.offsetHeight ? window.innerHeight - el.offsetHeight : topA;
                            //判断x轴还是y轴移动:当xy均存在或均不存在时默认xy轴均能拖拽,仅x则x轴拖拽,仅y则y轴拖拽
                            if((x&&y)||(!x && !y)){
                                el.style.left = left + 'px';
                                el.style.top = top + 'px';
                            }else if(x){
                                el.style.left = left + 'px';
                            }else if(y){
                                el.style.top = top + 'px';
                            }
                        }
                        //document的鼠标弹起事件:清空鼠标移动和弹起事件
                        document.onmouseup = (e)=>{
                            document.onmousemove = null;
                            document.onmouseup = null;
                        }
                    }
                }
            }
        }
        */
    })
</script>
原文地址:https://www.cnblogs.com/snowstorm22/p/10364227.html