vue 拖拽

<template>
    <div class="drag-ball" ref="dragBall" @mousedown.stop.prevent="mousedown" @mouseup.stop.prevent="mouseup">
        <div class="drag-content">
            <slot name="value">{{ value }}</slot>
        </div>
    </div>
</template>
<script>
    export default {
        name: 'drag-ball',
        props: {
            value: {
                type: String,
                default: '悬浮球!'
            }
        },
        data() {
            return {
                canDrag: false,
                // 偏移
                inset: {
                    left: 0,
                    top: 0
                },
                // 移动
                move: {},
                // 位置
                position: {
                    left: 0,
                    top: 0
                },
                // 初始位置
                positionOld: {},
                startTime: null,
                endTime: null
            };
        },
        methods: {
            toNew() {
                alert('去新版');
            },

        mousedown(e) {
            if (!this.canDrag) {
                    this.startTime = e.timeStamp;
                    this.positionOld = this.getPosition(this.dragBall);
                    this.position = {
                        left: this.positionOld.left,
                        top: this.positionOld.top
                        //...this.positionOld
                    };
                    console.log(this.position);
                    console.log(e.clientX, e.clientY);
                    this.inset = {
                        left: e.clientX - this.positionOld.left,
                        top: e.clientY - this.positionOld.top
                    };
                    this.canDrag = true;
                }

            if (e.preventDefault) {
                e.preventDefault();
            } else{
                e.returnValue=false;
            };
            const _this = this
            document.onmousemove=function (e) {
                if (_this.canDrag) {
                    let left = e.clientX - _this.inset.left;
                    let top = e.clientY - _this.inset.top;
                    if (left < 0) {
                        left = 0;
                    } else if (left > (window.innerWidth - _this.dragBall.offsetWidth)) {
                        left = window.innerWidth - _this.dragBall.offsetWidth;
                    }
                    if (top < 0) {
                        top = 0;
                    } else if (top > (window.innerHeight - _this.dragBall.offsetHeight)) {
                        top = window.innerHeight - _this.dragBall.offsetHeight;
                    }
                    _this.dragBall.style.left = left + 'px';
                    _this.dragBall.style.top = top + 'px';
                    _this.move = {
                        x: left - _this.positionOld.left,
                        y: top - _this.positionOld.top
                    };
                    _this.position = {
                        left,
                        top
                    };
                }
            }
        },


          
         
            mouseup(e) {
                if (this.canDrag) {
                    this.endTime = e.timeStamp;
                    if (this.endTime - this.startTime > 100 || Math.abs(this.move.x) > 2 || Math.abs(this.move.y) > 2) {
                        // 非单击事件
                        if ((this.position.left + this.dragBall.offsetWidth / 2) > window.innerWidth / 2) {
                            this.dragBall.style.left = window.innerWidth - this.dragBall.offsetWidth + 'px';
                        } else {
                            this.dragBall.style.left = 0 + 'px';
                        }
                    } else {
                        this.$emit('click');
                    }
                    this.inset = {};
                    this.move = {};
                    this.position = {};
                    this.canDrag = false;
                }
            },
            
            // 获取dom的绝对位置
            getPosition(source) {
                let left = source.offsetLeft; //获取元素相对于其父元素的left值var left
                let top = source.offsetTop;
                let current = source.offsetParent; // 取得元素的offsetParent // 一直循环直到根元素
                while (current != null) {
                    left += current.offsetLeft;
                    top += current.offsetTop;
                    current = current.offsetParent;
                }
                return {
                    left: left,
                    top: top
                };
            }
        },
        computed: {
            dragBall() {
                console.log(this.$refs.dragBall)
                return this.$refs.dragBall;
            }
        }
    };

</script>
<style scoped>
    .drag-ball {
        position: fixed;
        z-index: 10003;
        right: 0;
        top: 70%;
         5em;
        height: 5em;
        background: deepskyblue;
        border-radius: 50%;
        overflow: hidden;
        box-shadow: 0px 0px 10px 2px skyblue;
        display: flex;
        align-items: center;
        justify-content: center;
        padding: 1em;
        user-select: none;
    }

    .drag-ball .drag-content {
        overflow-wrap: break-word;
        font-size: 14px;
        color: #fff;
        letter-spacing: 2px;
    }

</style>

直接mousemove的话   会发生移动卡顿。

原文地址:https://www.cnblogs.com/HePandeFeng/p/13999501.html