vue2 element ui dialog拖拽功能实现。
完整实现代码
1. 创建指令文件(推荐)
新建
src/directives/drag.js
import Vue from 'vue'
Vue.directive('drag', {
bind(el) {
// 获取 Dialog 标题栏和内容区
const dialogHeader = el.querySelector('.el-dialog__header')
const dialogDrag = el.querySelector('.el-dialog')
if (!dialogHeader || !dialogDrag) return
// 鼠标样式
dialogHeader.style.cursor = 'move'
// 必须用 fixed 定位,才能自由拖动
dialogDrag.style.position = 'fixed'
// 每次打开弹窗 → 强制重置居中
const resetCenter = () => {
const clientWidth = document.documentElement.clientWidth
const clientHeight = document.documentElement.clientHeight
const dialogWidth = dialogDrag.offsetWidth
const dialogHeight = dialogDrag.offsetHeight
// 计算居中位置
dialogDrag.style.left = (clientWidth - dialogWidth) / 2 + 'px'
dialogDrag.style.top = (clientHeight - dialogHeight) / 2 + 'px'
dialogDrag.style.margin = 0 // 清除 Element 默认居中
}
// 监听 Dialog 显示(每次打开都会重新居中)
const ob = new MutationObserver(() => {
if (el.style.display !== 'none') {
resetCenter()
}
})
ob.observe(el, { attributes: true, attributeFilter: ['style'] })
// 拖拽逻辑
dialogHeader.onmousedown = e => {
const offsetX = e.clientX - dialogDrag.getBoundingClientRect().left
const offsetY = e.clientY - dialogDrag.getBoundingClientRect().top
document.onmousemove = moveEvent => {
let left = moveEvent.clientX - offsetX
let top = moveEvent.clientY - offsetY
// 边界限制
const maxLeft =
document.documentElement.clientWidth -
dialogDrag.offsetWidth
const maxTop =
document.documentElement.clientHeight -
dialogDrag.offsetHeight
left = Math.max(0, Math.min(left, maxLeft))
top = Math.max(0, Math.min(top, maxTop))
dialogDrag.style.left = left + 'px'
dialogDrag.style.top = top + 'px'
}
document.onmouseup = () => {
document.onmousemove = null
document.onmouseup = null
}
e.preventDefault()
}
}
})
2. 在 main.js 全局注册
import Vue from 'vue'
import App from './App.vue'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
// 引入拖拽指令
import './directives/drag'
Vue.use(ElementUI)
new Vue({
el: '#app',
render: h => h(App)
})
3. 在 Dialog 上使用 v-drag
直接在 el-dialog 标签上添加 v-drag 即可
<template>
<div>
<el-button @click="dialogVisible = true">打开可拖动 Dialog</el-button>
<!-- 只需要加 v-drag 指令 -->
<el-dialog
v-drag
title="可拖动对话框"
:visible.sync="dialogVisible"
width="500px"
>
<span>这是一个可以拖动的 Dialog ✨</span>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="dialogVisible = false">确定</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
export default {
data() {
return {
dialogVisible: false
}
}
}
</script>
浙公网安备 33010602011771号