帮我实现一个拖拽弹窗头部的vue 自定义指令
时间: 2023-07-07 08:30:57 浏览: 107
好的,以下是一个实现拖拽弹窗头部的 Vue 自定义指令:
```js
// draggable.js
const draggable = {
bind: function(el, binding, vnode) {
let isDragging = false;
let x = 0;
let y = 0;
let initialX = 0;
let initialY = 0;
el.style.cursor = 'move';
function mouseDown(e) {
initialX = e.clientX - x;
initialY = e.clientY - y;
if (e.target === el) {
isDragging = true;
}
}
function mouseMove(e) {
if (isDragging) {
x = e.clientX - initialX;
y = e.clientY - initialY;
el.style.transform = `translate3d(${x}px, ${y}px, 0)`;
}
}
function mouseUp(e) {
isDragging = false;
}
el.addEventListener('mousedown', mouseDown);
el.addEventListener('mousemove', mouseMove);
el.addEventListener('mouseup', mouseUp);
el._cleanup = function() {
el.removeEventListener('mousedown', mouseDown);
el.removeEventListener('mousemove', mouseMove);
el.removeEventListener('mouseup', mouseUp);
};
},
unbind: function(el, binding, vnode) {
el._cleanup && el._cleanup();
}
};
export default draggable;
```
这个自定义指令实现了在鼠标按下时将弹窗拖动到指定位置的功能。指令会在绑定时给指定的元素添加 mousedown、mousemove 和 mouseup 事件监听器,当鼠标按下时,记录下当前鼠标位置和弹窗位置的偏移量,并将 isDragging 状态设置为 true;当鼠标移动时,根据当前鼠标位置和偏移量计算出弹窗的新位置,并使用 CSS transform 属性将其移动到指定位置;当鼠标松开时,将 isDragging 状态设置为 false。
使用这个自定义指令非常简单,只需要在弹窗头部元素上添加 v-draggable 指令即可:
```html
<template>
<div class="modal">
<div class="modal-header" v-draggable>
<h3 class="modal-title">{{ title }}</h3>
<button class="modal-close" @click="$emit('close')">x</button>
</div>
<div class="modal-body">
<slot></slot>
</div>
</div>
</template>
<script>
import draggable from './draggable';
export default {
directives: {
draggable
},
props: {
title: String,
visible: Boolean
}
};
</script>
<style scoped>
.modal {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: white;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
}
.modal-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 10px;
background-color: #eee;
cursor: move;
}
.modal-title {
margin: 0;
}
.modal-close {
border: none;
background-color: transparent;
font-size: 20px;
cursor: pointer;
}
</style>
```
在这个组件中,我们将 v-draggable 指令绑定到了弹窗头部的元素上。指令会自动添加鼠标事件监听器,并在鼠标拖拽时实现弹窗的移动效果。
阅读全文