vue3使用自定义指令简单实现一个可拖拽弹窗组件
<!DOCTYPE html>
<html lang="zh-CN"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>可拖拽弹窗</title><!-- 引入 Vue CDN --><script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script><style>.drag-dialog {position: fixed;background: white;border: 1px solid #ccc;border-radius: 4px;padding: 20px;box-shadow: 0 2px 12px rgba(0, 0, 0, 0.15);}.dialog-header {cursor: move;padding: 10px;background: #f5f5f5;margin: -20px -20px 10px -20px;border-radius: 4px 4px 0 0;user-select: none;}.dialog-body {padding: 10px 0;}.dialog-footer {text-align: right;margin-top: 20px;}button {padding: 6px 12px;margin-left: 10px;cursor: pointer;}</style>
</head><body><div id="app"><button @click="showDialog">打开弹窗</button><div class="drag-dialog" v-show="visible" :style="dialogStyle" v-drag><div class="dialog-header">可拖拽弹窗标题</div><div class="dialog-body">这是弹窗内容</div><div class="dialog-footer"><button @click="visible = false">关闭</button><button @click="handleConfirm">确定</button></div></div></div><script>javascript">const app = Vue.createApp({data() {return {visible: false,dialogStyle: {left: '50%',top: '50%',transform: 'translate(-50%, -50%)'}}},methods: {showDialog() {this.visible = true;},handleConfirm() {alert('点击了确定按钮');this.visible = false;}}});// 注册自定义指令app.directive('drag', {mounted(el) {el.style.position = 'fixed';const header = el.querySelector('.dialog-header');header.onmousedown = function (e) {// 鼠标按下时的位置const startX = e.clientX;const startY = e.clientY;// 当前元素的位置const left = el.offsetLeft;const top = el.offsetTop;document.onmousemove = function (e) {// 计算移动距离const moveX = e.clientX - startX;const moveY = e.clientY - startY;// 更新位置el.style.left = left + moveX + 'px';el.style.top = top + moveY + 'px';};document.onmouseup = function () {document.onmousemove = null;document.onmouseup = null;};};}});app.mount('#app');</script>
</body></html>