拖拽组件实现原理

直接进主题:
1、做拖拽组件 核心是要设置组件绝对定位
平且设置动态的style: left top动态变化就行

<template>
    <div
        @mousedown="handleMouseDown"
        class="locationWidget"
        :class="{ active: isActive }"
        :style="{
            'margin-top': (widget.marginTop || 0) + 'px',
            'margin-bottom': (widget.marginBottom || 0) + 'px',
            left: pos.left + 'px',
            top: pos.top + 'px'
        }"
    >
        <div>广州xxxxx</div>
        <handle v-if="isActive" @deleteWidget="deleteWidget" />
    </div>
</template>
<style lang="less" scoped>
.locationWidget {
    position: absolute;
    cursor: all-scroll;
    z-index: 100;
    width: 100px;
}
</style>

2、添加一个mousedown事件给组件

  export default {
    name: 'locationWidget',
    components: {
        nullData,
        handle
    },
    props: {
        widget: {
            type: Object,
            default() {
                return {
                    type: 'locationWidget',
                    name: '城市定位'
                };
            }
        },
        isActive: Boolean
    },
    data() {
        return {
            pos: {
                top: 0,
                left: 0
            }
        };
    },
    computed: {},
    watch: {},
    created() {},
    mounted() {},
    methods: {
       
        // 点击鼠标
        handleMouseDown(e) {
            e.stopPropagation();
            const pos = {
                ...this.pos
            };
            const startY = e.clientY;
            const startX = e.clientX;
            // 如果直接修改属性,值的类型会变为字符串,所以要转为数值型
            const startTop = Number(pos.top);
            const startLeft = Number(pos.left);

            const move = moveEvent => {
                const currX = moveEvent.clientX;
                const currY = moveEvent.clientY;
                pos.top = currY - startY + startTop;
                pos.left = currX - startX + startLeft;
                // 边界处理
                if (pos.top < 0) pos.top = 0; // 不能超出顶部
                if (pos.left < 0) pos.left = 0; // 不能超出左边
                if (pos.left > 275) pos.left = 275; // 不能超出右边
                this.pos = pos;
                console.log('this.pos', this.pos);
            };

            const up = () => {
                document.removeEventListener('mousemove', move);
                document.removeEventListener('mouseup', up);
            };

            document.addEventListener('mousemove', move);
            document.addEventListener('mouseup', up);
        }
    }
};
</script>

按照上面 点击鼠标 就会触发handleMouseDown
会绑定2个事件给document: move、 up事件
document.addEventListener(‘mousemove’, move);
document.addEventListener(‘mouseup’, up);

核心逻辑move事件, 移动鼠标就触发
就能够拿到当前鼠标位置 startY,startX
startTop 是组件旧的top值
startLeft 是组件旧的left值

鼠标 移动到新的地方后, 鼠标当前的currY - 开始的startY 就是移动的Y值 ,currX - startX 就是移动的X值
X Y值分别加上 原来的startLeft、startTop就是新的left 、top值了
pos.top = currY - startY + startTop;
pos.left = currX - startX + startLeft;
然后记录下当前的top、left
this.pos = pos;

鼠标释放后 触发up事件
up事件就是解绑mouseup、mouseup事件,即可

原理很简单吧!

看图拖拽组件实现原理_第1张图片

总结:核心原理 通过鼠标滑动 计算增加的x\y值 然后重写给组件设置位置的样式,left\top值变化就行

你可能感兴趣的:(前端干货,vue技术,javascript,前端,es6)