1. 程式人生 > 實用技巧 >vue 拖拽

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%; width: 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的話 會發生移動卡頓。